美文网首页
【Spring源码】23.AOP之代理执行时@EnableAsp

【Spring源码】23.AOP之代理执行时@EnableAsp

作者: 天还下着毛毛雨 | 来源:发表于2023-03-16 22:21 被阅读0次

1. 前言

前面讲到,以JDK动态代理方式 的代理对象已经创建成功,spring中 使用JDK动态代理时,传入的InvokeHandler是JdkDynamicAopProxy类型。

image.png

并且数据结构是这样的

并且他的AdvisedSupport advised 属性是 proxyFactory{

            advisors :符合该类的所有的切面,

            targetSource:被代理目标对象

            proxyTargetClass :代理的方式

}

那么实现InvokeHandler接口,那么代理对象调用方法时,就会调入Invoke方法 来进行具体的增强。spring aop的具体代理逻辑就在这个方法中。


image.png

2. equals和hashCode方法不进行代理

首先进来会取出代理的目标对象,this.advised.targetSource

然后进行equals()和hashCode()的判断,这两个方法 是不会代理的,直接调用原生方法

image.png

3. @EnableAspectJAutoProxy配置exposeProxy=true,暴露代理对象

然后如果@EnableAspectJAutoProxy配置的exposeProxy为true的话,

@EnableAspectJAutoProxy(proxyTargetClass = false,exposeProxy = true)

会将代理对象提前放入 ThreadLocal里面,供代理过程中其他地方获取

image.png

应用场景

这个挺有用的。比如 某个类的 proxyMethodA() 和 proxyMethodB()都会命中切面,被代理。如果以下面proxyMethodA方法内部直接 调用proxyMethodB()方法,

其实 调用的原生对象的proxyMethodB()方法,是不会走 proxyMethodB()的代理逻辑的。

@Component
public class ProxyClass implements InterFace {
    public void proxyMethodA() {
        proxyMethodB();
    }

    public void proxyMethodB() {
    }
}

所以,我们要去获取ProxyClass的代理对象来在proxyMethodA()的方法内部 调用proxyMethodB()

注入自己的代理对象

一种是自己注入自己,那么肯定注入进来的是代理对象,那么用代理对象去调用它的 proxyMethodB()方法,肯定是会走代理的。

@Component
public class ProxyClass implements MyBeanService {

    @Autowired
    ProxyClass proxyClass;

    public void proxyMethodA() {
        // 注入进来的是 proxyClass代理对象
        proxyClass.proxyMethodB();
    }
    public void proxyMethodB() {
    }

}

AopContext.currentProxy()

还有一种就是 上面源码里的AopContext.currentProxy()

会把代理对象放入ThreadLocal中,

直接在 proxyMethodA() 方法内部AopContext.currentProxy()获取到代理对象,然后调用它的proxyMethodB()

public class ProxyClass implements MyBeanService {

    public void proxyMethodA() {
        Object o = AopContext.currentProxy();
        ((ProxyClass)o).proxyMethodB();
    }

    public void proxyMethodB() {
    }
}

相关文章

网友评论

      本文标题:【Spring源码】23.AOP之代理执行时@EnableAsp

      本文链接:https://www.haomeiwen.com/subject/mcidrdtx.html