Spring旅程(四) AOP–Spring AOP实例

最后更新于:2022-04-01 14:50:13

上篇讲述了[Spring的AOP](http://blog.csdn.net/lovesummerforever/article/details/22664647)[原理](http://blog.csdn.net/lovesummerforever/article/details/22664647),本篇将上篇中使用的动态代理解决独立服务的问题用SpirngAOP来实现。 ### 采用配置文件的方式。 1、导入相应的Spring jar包。 2、[在SpringIOC中的步骤123中已经给出](http://blog.csdn.net/lovesummerforever/article/details/22646793)。 3、将横切性关注的问题模块化,建立安全处理类。在SecurityHandler类中写我们的独立方法,也就是定义Advice(具体实现),代码如下。 ~~~ public class SecurityHandler { private void checkSecurity() { System.out.println("-------checkSecurity-------"); } } ~~~ 4、在配置文件中进行相关配置。applicationContext.xml代码如下所示。 ~~~ <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <bean id="userManager" class="com.bjpowernode.spring.UserManagerImpl"/> <bean id="securityHandler" class="com.bjpowernode.spring.SecurityHandler"/> <aop:config> <aop:aspect id="secutityAspect" ref="securityHandler"> <!-- 以add开头的方法 <aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/> --> <!-- com.bjpowernode.spring.*包下的所有方法. <aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.*(..))"/> --> <aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.add*(..)) || execution(* com.bjpowernode.spring.*.del*(..))"/> <aop:before method="checkSecurity" pointcut-ref="addAddMethod"/> </aop:aspect> </aop:config> </beans> ~~~ 需要说明几点 指定SecutityHander为aspect:    <aop:aspectid="secutityAspect" ref="securityHandler"> Pointcut(切入点)以及事务范围,在这里用于所有的add和del方法上:<aop:pointcutid="addAddMethod" expression="execution(*com.bjpowernode.spring.*.add*(..)) || execution(*com.bjpowernode.spring.*.del*(..))"/> 设置通知类型并指向哪个切入点: <aop:beforemethod="checkSecurity" pointcut-ref="addAddMethod"/> 将目标类UsemrManagerImpl和Aspect类SecurityHandler配置到Spring的IOC中:<beanid="userManager"class="com.bjpowernode.spring.UserManagerImpl"/> <bean id="securityHandler"class="com.bjpowernode.spring.SecurityHandler"/> 5、客户端调用代码如下所示。 ~~~ import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Client { public static void main(String[] args) { BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml"); UserManager userManager = (UserManager)factory.getBean("userManager"); userManager.delUser(1); } } ~~~ 上述基本上完成了一个SpringAOP的实例。 ### 如果我们在advice中,也就是在我们的安全性方法中想要获取客户端的数据该如何获取呢? 我们可以在这个方法中添加参数,也就是我们JoinPoint,通过传递这个对象,我们可以去得到参数值,SecurityHandler类的代码如下所示。 ~~~ public class SecurityHandler { private void checkSecurity(JoinPoint joinPoint) { //取得参数. for(int i=0;i<joinPoint.getArgs().length;i++) { System.out.println(joinPoint.getArgs()[i]); } System.out.println(joinPoint.getSignature().getName()); System.out.println("-------checkSecurity-------"); } } ~~~ ### 当然我们也可以采用注解的方式来实现。 1、采用注解的方式首先要加入一些jar包,*Spring_home/spring-framework-2.0\lib\aspectj\aspectjrt.jar aspectjweaver.jar 2、SecurityHandler类的代码如下所示。和上面的通过配置文件方式进行对比,很快就会懂得不同的标签不同的含义。 ~~~ import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; @Aspect public class SecurityHandler { /** * 定义Pointcut,Pointcut的名称为addAddMethod(),此方法没有返回值和参数 * 该方法就是一个标识,不进行调用 */ @Pointcut("execution(* add*(..))") private void addAddMethod(){}; /** * 定义Advice,表示我们的Advice应用到哪些Pointcut订阅的Joinpoint上 */ @Before("addAddMethod()") //@After("addAddMethod()") private void checkSecurity() { System.out.println("-------checkSecurity-------"); } } ~~~ 3、applicationContext.xml文件中配置aspect类和目标类UserManagerImpl,同时配置实用Annotation方式,代码如下所示。 ~~~ <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <!-- 启用AspectJ对Annotation的支持 --> <aop:aspectj-autoproxy/> <bean id="userManager" class="com.bjpowernode.spring.UserManagerImpl"/> <bean id="securityHandler" class="com.bjpowernode.spring.SecurityHandler"/> </beans> ~~~ 4、客户端调用和配置XML方式一样。 是不是关于SpirngAOP,渐渐的懂些了。
';