spring aop 内部方法与aspectJ

1)spring aop与aspectJ

AspectJ 本身是不支持运行期织入的(编译时、编译后、加载时,Spring是运行期,https://www.cnblogs.com/silyvin/p/11260965.html是加载时),日常使用时候,我们经常回听说,spring 使用aspectJ实现了aop,听起来好像spring的aop完全是依赖于aspectJ

其实spring对于aop的实现是通过动态代理(jdk的动态代理或者cglib的动态代理),它只是使用了aspectJ的Annotation,并没有使用它的编译和织入器,关于这个可以看这篇文章 ,也就是说spring并不是直接使用aspectJ实现aop的

spring aop与aspectJ的区别

看了很多篇博客以及源码,我对spring aop与aspectJ的理解大概是这样;
1)spring aop 使用AspectJ语法的一个子集,一些method call, class member set/get 等aspectJ支持的语法它都不支持
2)spring aop 底层是动态代理,所以受限于这点,有些增强就做不到,比如 调用自己的方法就无法走代理

 



作者:端吉
链接:https://www.jianshu.com/p/958af6a90477
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
 
2)spring aop 内部函数拦截

看下下面的例子:

@Component
public class A{
    public void method1(){
        method2();
    }

    public void method2(){
       //...
    }
}

这个时候method2是无法被切到

之前碰到这样的问题时,我还特别不能理解,现在想下aop的底层实现方式就很容易理解了。

在之前写的jdk动态代理与cglib动态代理实现原理,我们知道了jdk动态代理是通过动态生成一个类的方式实现的代理,也就是说代理是不会修改底层类字节码

为啥method2()没有被切到,因为a.method1()执行的方法,最后调用的不是 代理对象.method2(),而是它自己的method2()(this.method2()) 这个方法本身没有任何改动

作者:端吉
链接:https://www.jianshu.com/p/958af6a90477
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
 
解决方案有二:

1 ,要想被切到可以通过如下奇葩的方式:

@Component
public class A{
        
    @Autowired
    private A a;

    public void method1(){
        a.method2();
    }

    public void method2(){
       //...
    }
}


2)

在内部调用时重新获得代理对象
public class ServiceAImpl implements ServiceA{
ServiceAImpl serviceA;
public void function01(...){
...
serviceA = SpringContextUtil.getBeanByClass(this.getClass());
serviceA.function02(...);
}
...
public void function02(...){
doSomeThing;
}
}
---------------------
作者:russ44
来源:CSDN
原文:https://blog.csdn.net/russ44/article/details/78975997
版权声明:本文为博主原创文章,转载请附上博文链接!

posted on 2019-07-28 19:49  silyvin  阅读(722)  评论(0编辑  收藏  举报