在Spring中实现AOP根据版本不同,可以有大致四种配置方式。现简
单列一下。在介绍Spring的AOP配置方式
前,先要注意Spring中Ad
visor的概念。在Spring中Advisor是Advice和Pointcut的结
合,但它还不是AOP概念上的Aspect
。因为在Spring中Advisor还是Spring用来生成Aspect对象的一个原型
,根据配置的不同,S
pring可以只对某个类生成Aspect,也可以对所有的类生成Aspe
ct。
1. 基于xml配置文件的代理配置方式
这种方式在2.0以后很少用了,原因是配置项过多,过于繁琐。但对于理解Spring AOP还是很有帮助 的
1.1 定义通知
<bean id="advice" class="yourAdviceImpl" />
1.2 定义切点
要定义一个切点,可以选择使用正 则表达式方式声明的切点或者Aspe ctJ方式声明的切点。对正则表达式切点,使用Perl5RegexpMethodPointcut或JdkRegexpMethodPointcut(Java 1.4以上版本,不需要Jakarta ORO的支持了);对AspectJ切点,使用AspectJExpressPointcut
<bean id="pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value="yourRegularExpression" />
</bean>
<bean id="pointcut" class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
<property name="expression" value="yourAspectJExpression" />
</bean>
1.3 定义通知者
DefaultPointcutAdviso r是Spring提供的默认通知者,它需要提供通知和切点的引 用。
Spring也提供了RegexpMethodPointcutAdvisor和AspectJExpressionPointcutAdvisor来对应两种声明切点的方式,不用再单独定义切点 。
<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdv isor">
<property name="advice" ref="advice" />
<property name="pointcut" ref="pointcut" />
</bean>
<bean id="advisor" class="org.springframework.aop.support.Re gexpMethodPointcutAdviso r">
<property name="advice" ref="adv ice" / >
<property name="pattern" value="yourRegularExpression " />
</bean>
<bean id="advisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
<property name="advice" ref="advice" />
<property name="expression" value="yourAspectjExpression" />
</bean>
1.4 定义ProxyFacto ryBean
<bean id="yourBean" class="org.springframework.aop.framework.ProxyFactory Bean>
<property name="target" ref="yourTargetBean" />
<property name="interceptorNames" value="a dvisor" />
<property name="p roxyInterfaces" value= "interfa ceClass" />
</bean>
interceptorNames和proxyInterfaces都是数组属性,所以可以声明要使用的一个list,也可以让Spring自动把单个值转化为数组
上面明确定义了要对那个 targ etBean应 用代理生成切面实例 。如果不想限制targetBean,可以 让Spring为所有匹配切点声明的bean生成切面实例, 这样就不用一个个定义ProxyFactor yBean了,只 需要定义
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdviso rAutoProxyCreator" />
这是一个BeanPostProcessor,所以Spring会自动识别并在bean的声明周期使用
2 利用2.0以后使用aop标签
<aop:config>
<aop:aspect ref="">
<aop:pointcut id ="performance" expression="execu tion(* *.perform(..)) " />
<aop:before method="" poin tcut-ref="performa nce" />
<aop:before method="" pointcut="execution(* *.perform(..))" />
<aop:after-returning method="" pointcut="execution( * *.perform(..))" />
<aop:afte r-throwing method="" pointcut="execution(* *.perform(..))" />
</aop:aspect>
</aop:config>
3 利用Annotation
3.1 利用@Aspect将一个POJO类声明为一个切面。
3.2 定义切点
@Pointcut(" execution(* *.perform(..)) ")
public void performance(){}
通过@Pointcut定义的切点的名字就是它所注解的方法的名字,因此例子中的切点名字是
performance()。这里声明的perfor mance()方法实际圣只是一个标记,为@Pointcut提供附加的点,并不要求有实际意义。
3.3 定义通知
对要执行切面的方法,通过@Before("performance()"), @AfterReturning
("performance()")来定义通知。注意 这里提供的切点名称,是performance(),而不是perform ance
如果对上面的两点不是很理解,也可以省略@Pointcut,而将AspectJ表达式直接定义在@Befor e等通知中,将上面的两步合为一步,如@Before("execution(* *.perform(..))")
3.4 通知Spring创建代理
<aop:aspectj-autoproxy>
这实际上相当于声明了一个AnnotationAwareAspectJAutoProxyCreator,从而根据@Pointcut声明的切点来自动代理匹配的bean实例
4 在Spring中结合进AspectJ
对于超出Spring AOP支持范围的,可以采用这种方式。只需要在Spring中配置AspectJ的Class实例时让S pring能够获得 AspectJ类的实例就可以了,比如
<bean class="a_aspectj_class" factory-method="aspectOf">
<preperty .... />
</bean>
1. 基于xml配置文件的代理配置方式
这种方式在2.0以后很少用了,原因是配置项过多,过于繁琐。但对于理解Spring AOP还是很有帮助 的
1.1 定义通知
<bean id="advice" class="yourAdviceImpl" />
1.2 定义切点
要定义一个切点,可以选择使用正 则表达式方式声明的切点或者Aspe ctJ方式声明的切点。对正则表达式切点,使用Perl5RegexpMethodPointcut或JdkRegexpMethodPointcut(Java 1.4以上版本,不需要Jakarta ORO的支持了);对AspectJ切点,使用AspectJExpressPointcut
<bean id="pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value="yourRegularExpression" />
</bean>
<bean id="pointcut" class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
<property name="expression" value="yourAspectJExpression" />
</bean>
1.3 定义通知者
DefaultPointcutAdviso r是Spring提供的默认通知者,它需要提供通知和切点的引 用。
Spring也提供了RegexpMethodPointcutAdvisor和AspectJExpressionPointcutAdvisor来对应两种声明切点的方式,不用再单独定义切点 。
<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdv isor">
<property name="advice" ref="advice" />
<property name="pointcut" ref="pointcut" />
</bean>
<bean id="advisor" class="org.springframework.aop.support.Re gexpMethodPointcutAdviso r">
<property name="advice" ref="adv ice" / >
<property name="pattern" value="yourRegularExpression " />
</bean>
<bean id="advisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
<property name="advice" ref="advice" />
<property name="expression" value="yourAspectjExpression" />
</bean>
1.4 定义ProxyFacto ryBean
<bean id="yourBean" class="org.springframework.aop.framework.ProxyFactory Bean>
<property name="target" ref="yourTargetBean" />
<property name="interceptorNames" value="a dvisor" />
<property name="p roxyInterfaces" value= "interfa ceClass" />
</bean>
interceptorNames和proxyInterfaces都是数组属性,所以可以声明要使用的一个list,也可以让Spring自动把单个值转化为数组
上面明确定义了要对那个 targ etBean应 用代理生成切面实例 。如果不想限制targetBean,可以 让Spring为所有匹配切点声明的bean生成切面实例, 这样就不用一个个定义ProxyFactor yBean了,只 需要定义
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdviso rAutoProxyCreator" />
这是一个BeanPostProcessor,所以Spring会自动识别并在bean的声明周期使用
2 利用2.0以后使用aop标签
<aop:config>
<aop:aspect ref="">
<aop:pointcut id ="performance" expression="execu tion(* *.perform(..)) " />
<aop:before method="" poin tcut-ref="performa nce" />
<aop:before method="" pointcut="execution(* *.perform(..))" />
<aop:after-returning method="" pointcut="execution( * *.perform(..))" />
<aop:afte r-throwing method="" pointcut="execution(* *.perform(..))" />
</aop:aspect>
</aop:config>
3 利用Annotation
3.1 利用@Aspect将一个POJO类声明为一个切面。
3.2 定义切点
@Pointcut(" execution(* *.perform(..)) ")
public void performance(){}
通过@Pointcut定义的切点的名字就是它所注解的方法的名字,因此例子中的切点名字是
performance()。这里声明的perfor mance()方法实际圣只是一个标记,为@Pointcut提供附加的点,并不要求有实际意义。
3.3 定义通知
对要执行切面的方法,通过@Before("performance()"), @AfterReturning
("performance()")来定义通知。注意 这里提供的切点名称,是performance(),而不是perform ance
如果对上面的两点不是很理解,也可以省略@Pointcut,而将AspectJ表达式直接定义在@Befor e等通知中,将上面的两步合为一步,如@Before("execution(* *.perform(..))")
3.4 通知Spring创建代理
<aop:aspectj-autoproxy>
这实际上相当于声明了一个AnnotationAwareAspectJAutoProxyCreator,从而根据@Pointcut声明的切点来自动代理匹配的bean实例
4 在Spring中结合进AspectJ
对于超出Spring AOP支持范围的,可以采用这种方式。只需要在Spring中配置AspectJ的Class实例时让S pring能够获得 AspectJ类的实例就可以了,比如
<bean class="a_aspectj_class" factory-method="aspectOf">
<preperty .... />
</bean>