Spring AOP 的應(yīng)用演變

1.Spring AOP - ProxyFactoryBean,他是通過Spring FactoryBean的原理把代理對象注入Spring容器種

@Bean
public ProxyFactoryBean userServiceProxy(){

? ? UserService userService = new UserService();
? ? ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
????proxyFactoryBean.setTarget(userService);
????proxyFactoryBean.addAdvice(new MethodInterceptor() {
????????@Override
????????public Object invoke(MethodInvocation invocation) throws Throwable
????????????System.out.println("before...");
????????????Object result = invocation.proceed();
????????????System.out.println("after...");
????????????return result;
? ? ? ? ? }});
? ? ? ? ? ?return proxyFactoryBean;
}
2.ProxyFactoryBean還有額外的功能,比如可以把某個Advise或Advisor定義成為Bean,然后在 ProxyFactoryBean中進(jìn)行設(shè)置
@Bean
public MethodInterceptor zhouyuAroundAdvise(){
????return new MethodInterceptor() {
????????@Override
????????public Object invoke(MethodInvocation invocation) throws Throwable {
????????????System.out.println("before...");
????????????Object result = invocation.proceed();
????????????System.out.println("after...");
????????????return result;
????????}};
}

@Bean
public ProxyFactoryBean userService(){
????UserService userService = new UserService();
????ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
????proxyFactoryBean.setTarget(userService);
????proxyFactoryBean.setInterceptorNames("zhouyuAroundAdvise");
????return proxyFactoryBean;
}

3.上面的方式可以發(fā)現(xiàn)只能指定特定的被代理類去代理,如果有多個被代理類,那要一個一個去加入所以我們會有BeanNameAutoProxyCreator ,通過BeanNameAutoProxyCreator可以對批量的Bean進(jìn)行AOP,并且指定了代理邏輯,指定了一個InterceptorName,也就是一個Advise,前提條件是這個Advise也得是一個Bean,這樣Spring才能找到的

@Bean
public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
????BeanNameAutoProxyCreator beanNameAutoProxyCreator = new ????BeanNameAutoProxyCreator();
????beanNameAutoProxyCreator.setBeanNames("userSe*");
????beanNameAutoProxyCreator.setInterceptorNames("zhouyuAroundAdvise");
????beanNameAutoProxyCreator.setProxyTargetClass(true);
????return beanNameAutoProxyCreator;
}
4.但是BeanNameAutoProxyCreator的缺點(diǎn)很明顯,它只能根據(jù)beanName來指定想要代理的Bean, 所以我們又有DefaultAdvisorAutoProxyCreator,
通過DefaultAdvisorAutoProxyCreator會直接去找所有Advisor類型的Bean,根據(jù)Advisor中的 PointCut和Advice信息,確定要代理的Bean以及代理邏輯,所以一般都會定義自己的Advisor然后注入到Spring容器種使之成為Bean。

@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor(){
????NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
????pointcut.addMethodName("test");
????DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
????defaultPointcutAdvisor.setPointcut(pointcut);
????defaultPointcutAdvisor.setAdvice(new ZhouyuAfterReturningAdvise());
????return defaultPointcutAdvisor;
}

@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
????DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new
????DefaultAdvisorAutoProxyCreator();
????return defaultAdvisorAutoProxyCreator;
}

5.但是,我們發(fā)現(xiàn),通過這種方式,我們得依靠某一個類來實(shí)現(xiàn)定義我們的Advisor,或者Advise,或者Pointcut,那么這個步驟能不能更加簡化一點(diǎn)呢?比如我們能不能只定義一個類,然后通過在類中的方法上通過某些注解,來定義PointCut以及Advice,可以的這就是我們的AspectJ,Spring支持了AspectJ的注解,對AspectJ注解提供了解析,比如:
@Aspect
@Component
public class ZhouyuAspect {
????@Before("execution(public void com.zhouyu.service.UserService.test())")
????public void zhouyuBefore(JoinPoint joinPoint) {
????System.out.println("zhouyuBefore");
????}
}
通過上面這個類,我們就直接定義好了所要代理的方法(通過一個表達(dá)式),以及代理邏輯(被@Before修飾的方法),簡單明了,這樣對于Spring來說,它要做的就是來解析這些注解了,解析之后得到對應(yīng)的Pointcut對象、Advice對象,生成Advisor對象,扔ProxyFactory中,進(jìn)而產(chǎn)生對應(yīng)的代理對象,具體怎么解析這些注解就是**@EnableAspectJAutoProxy注解**所要做的事情了,后面詳細(xì)分析。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容