侧边栏壁纸
博主头像
月伴飞鱼 博主等级

行动起来,活在当下

  • 累计撰写 39 篇文章
  • 累计创建 25 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

Spring 的 AOP 代理对象是在方法调用的时候动态创建的吗?

月伴飞鱼
2025-03-07 / 0 评论 / 1 点赞 / 13 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

Spring AOP 的代理对象是在 Bean 初始化阶段 创建的,而不是在方法调用时。

这样做有以下原因:

依赖注入的需要

在 Spring 中,代理对象需要注入到其他 Bean 中。

例如:

@Autowired 
private MyService myService; // 注入的是代理对象

如果代理对象在方法调用时才创建,那么在依赖注入阶段只能注入目标对象,这会导致切面逻辑无法生效。

性能优化

方法调用时动态创建代理对象会导致性能开销,包括生成代理类、实例化代理对象等。Spring 在 Bean 初始化阶段创建代理对象并缓存,可以避免这些开销。

生命周期管理

代理对象需要覆盖目标对象的整个生命周期,而不仅仅是在方法调用时。例如,在目标对象的生命周期回调(如 @PostConstruct 或销毁回调)中,也可能需要执行切面逻辑。

切面逻辑全生命周期覆盖

切面逻辑不仅适用于方法调用,还可能应用在依赖注入完成后的生命周期事件中。如果代理对象在调用时才创建,就无法覆盖这些场景。

代理对象的创建时机

Spring AOP 的代理对象是在 Bean 初始化阶段 完成的,具体过程如下:

  1. 实例化目标 Bean
    Spring 首先通过构造函数或工厂方法创建目标对象。

  2. 判断是否需要代理
    Spring 的 BeanPostProcessor 检查当前 Bean 是否需要代理,例如是否匹配 AOP 切面条件。如果需要代理,进入下一步。

  3. 生成代理类
    根据目标对象的类型,动态生成代理类:

    • 使用 JDK 动态代理 为实现了接口的目标对象生成代理类。

    • 使用 CGLIB 为没有实现接口的目标对象生成子类代理类。

  4. 实例化代理对象
    基于代理类创建一个代理对象,并将其注册到容器中,替代目标对象。

AOP 代理类和代理对象的关系

  1. 代理类
    动态生成的类,用于描述如何拦截目标对象的方法调用。例如,当目标类实现接口时,Spring 通过 JDK 动态代理生成类似以下代码的代理类:

public class MyServiceProxy implements MyService {
    private MyAspect aspect;
    private MyService target;

    public MyServiceProxy(MyService target, MyAspect aspect) {
        this.target = target;
        this.aspect = aspect;
    }

    @Override
    public void performTask() {
        aspect.beforeTask();
        target.performTask();
    }
}

代理对象
代理类的实例,是真正注入到容器中的对象。

它持有目标对象的引用,负责拦截方法调用并动态执行增强逻辑。例如:

MyService proxyInstance = new MyServiceProxy(new MyServiceImpl(), new MyAspect());

总结

代理对象并不是在方法调用时才创建,而是在 Bean 初始化阶段就完成了。

这是因为:

  • 保证依赖注入和生命周期管理。

  • 切面逻辑需要覆盖整个生命周期。

  • 方法调用时动态创建会导致性能问题。

公众号.png

1
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin
    1. 支付宝打赏

      qrcode alipay
    2. 微信打赏

      qrcode weixin
博主关闭了所有页面的评论