【代理】【七】代理源码解析-Cglib代理-为什么Spring中的代理方法互相调用 AOP 会失效,而原生的 Cglib 方法互相调用是会走增强的呢?

1  前言

今天我们来看个问题,我看源码的时候产生的困惑,就是我们都知道SpringAOP 我们方法中调用第二个方法,第二个方法不会走增强的逻辑,而原生的 Cglib 方法互相调用是会走增强的呢?我们看下现象:

1.1  原生 Cglib 方法互相调用

复制代码
public class UserServiceImpl {
    private String name;
    public void say() {
        System.out.println("111");
        say2();
    }

    public void say2() {
        System.out.println("222");
    }
}
public static void main(String[] args) {
    // 设置代理文件输出位置
    System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "./code");
    // 创建 cglib 代理类的核心对象
    Enhancer enhancer = new Enhancer();
    // 设置要创建代理的类
    enhancer.setSuperclass(UserServiceImpl.class);
    // 跟 JDK 代理一样,增强的逻辑
    enhancer.setCallback(new MyMethodInterceptor());
    // 创建代理,并调用
    UserServiceImpl userService = (UserServiceImpl) enhancer.create();
    userService.say();
}
复制代码

1.2  SpringAOP 方法互相调用

复制代码
public class A {
    public void say() {
        System.out.println("111");
        this.haha();
    }
    public void haha() {
        System.out.println("222");
    }
}
@Test
public void testFactoryBean() {
    System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "./code");
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring/spring-alias.xml");
    A a = applicationContext.getBean("a", A.class);
    a.say();
}
复制代码

是不是,看见没我们的Spring 第二个方法是不会走增强的,那么我们来看下为什么。

2  原生的为什么方法调用可以增强

我上节分析 Cglib 产生的类文件的执行过程,其实已经说过为什么它可以增强,主要的就是因为自始至终我们的对象都是代理对象自己,所以它调用自己的第二个方法也是会走增强的,我们回顾下过程:

3  Spring 为什么方法内部调用不会走增强

那么我们来看下Spring的为什么不会走增强,那首先我们得看下代理是怎么创建出来的,具体的创建过程我在讲AOP的时候都分析过了,我们这里简单看下哈:

3.1 创建代理

3.2 执行方法

当我们代理类执行第一个方法的时候,进入到这里的增强:

看见了吧,也就是说代理类的方法执行的时候,进入增强逻辑,当执行目标方法的时候,传的是我们被代理类的对象自己,所以么自己调自己就不会走增强了。

4 小结

好,本节解决了我们的疑惑看了下为什么Spring的方法调用增强不生效的道理,有理解不对的地方欢迎指正哈。

posted @   酷酷-  阅读(169)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示