1. 基於xml配置文件的代理配置方式
這種方式在2.0以後很少用了,原因是配置項過多,過於繁瑣。但對於理解Spring AOP還是很有幫助的
1.1 定義通知
<bean id="advice" class="yourAdviceImpl" />
1.2 定義切點
要定義壹個切點,可以選擇使用正則表達式方式聲明的切點或者AspectJ方式聲明的切點。對正則表達式切點,使用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 定義通知者
DefaultPointcutAdvisor是Spring提供的默認通知者,它需要提供通知和切點的引用。
Spring也提供了RegexpMethodPointcutAdvisor和AspectJExpressionPointcutAdvisor來對應兩種聲明切點的方式,不用再單獨定義切點。
<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="advice" />
<property name="pointcut" ref="pointcut" />
</bean>
<bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="advice" />
<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 定義ProxyFactoryBean
<bean id="yourBean" class="org.springframework.aop.framework.ProxyFactoryBean>
<property name="target" ref="yourTargetBean" />
<property name="interceptorNames" value="advisor" />
<property name="proxyInterfaces" value="interfaceClass" />
</bean>
interceptorNames和proxyInterfaces都是數組屬性,所以可以聲明要使用的壹個list,也可以讓Spring自動把單個值轉化為數組
上面明確定義了要對那個targetBean應用代理生成切面實例。如果不想限制targetBean,可以讓Spring為所有匹配切點聲明的bean生成切面實例,這樣就不用壹個個定義ProxyFactoryBean了,只需要定義
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
這是壹個BeanPostProcessor,所以Spring會自動識別並在bean的聲明周期使用
2 利用2.0以後使用aop標簽
<aop:config>
<aop:aspect ref="">
<aop:pointcut id="performance" expression="execution(* *.perform(..))" />
<aop:before method="" pointcut-ref="performance" />
<aop:before method="" pointcut="execution(* *.perform(..))" />
<aop:after-returning method="" pointcut="execution(* *.perform(..))" />
<aop:after-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()。這裏聲明的performance()方法實際聖只是壹個標記,為@Pointcut提供附加的點,並不要求有實際意義。
3.3 定義通知
對要執行切面的方法,通過@Before("performance()"),@AfterReturning
("performance()")來定義通知。註意這裏提供的切點名稱,是performance(),而不是performance
如果對上面的兩點不是很理解,也可以省略@Pointcut,而將AspectJ表達式直接定義在@Before等通知中,將上面的兩步合為壹步,如@Before("execution(* *.perform(..))")
3.4 通知Spring創建代理
<aop:aspectj-autoproxy>
這實際上相當於聲明了壹個AnnotationAwareAspectJAutoProxyCreator,從而根據@Pointcut聲明的切點來自動代理匹配的bean實例
4 在Spring中結合進AspectJ
對於超出Spring AOP支持範圍的,可以采用這種方式。只需要在Spring中配置AspectJ的Class實例時讓Spring能夠獲得AspectJ類的實例就可以了,比如
<bean class="a_aspectj_class" factory-method="aspectOf">
<preperty .... />
</bean>