aop代理类生成的调用链

本文详细解析了Spring框架中AOP代理的创建过程,从AbstractApplicationContext初始化到AnnotationAwareAspectJAutoProxyCreator生成代理类的完整调用链。通过深入源码,揭示了Spring如何在运行时动态创建代理对象,实现面向切面编程。

1,是谁生成的代理类,这里暂且记住是AnnotationAwareAspectJAutoPrxoyCreator这个类来生成的代理类。

2.下面是调用链
**加粗样式(1)AbstractApplicationContext.finishBeanFactoryInitialization(ConfigurableListableBeanFactory)
(2) DefaultListableBeanFactory.preInstantiateSingletons()
(3)AbstractBeanFactory.getBean(String)
(4)AbstractBeanFactory.doGetBean(String, Class, Object[],boolean)
(5)DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory<?>)
(6)AbstractBeanFactory.lambda$doGetBean0(String,RootBeanDefinition,Object[])(7)AbstractAutowireCapableBeanFactory.createBean(String,RootBeanDefinition,Object[])(8)AbstractAutowireCapableBeanFactory.doCreateBean(...)(9)AbstractBeanFactory.lambda0(String, RootBeanDefinition, Object[]) (7)AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[]) (8)AbstractAutowireCapableBeanFactory.doCreateBean(...) (9)AbstractBeanFactory.lambda0(String,RootBeanDefinition,Object[])(7)AbstractAutowireCapableBeanFactory.createBean(String,RootBeanDefinition,Object[])(8)AbstractAutowireCapableBeanFactory.doCreateBean(...)(9)AbstractBeanFactory.lambdadoGetBean$0(String, RootBeanDefinition, Object[])
(10)AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])
(11)AbstractAutowireCapableBeanFactory.doCreateBean(…)
(12)AbstractAutowireCapableBeanFactory.initializeBean(…)
(13)AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(.)
(14)AnnotationAwareAspectJAutoProxyCreator(AbstractAutoProxyCreator).postProcessAfterInitialization(…)
(15)AnnotationAwareAspectJAutoProxyCreator(AbstractAutoProxyCreator).wrapIfNecessary(… …
(16) AbstractAutoProxyCreator.createProxy(Class<?>, String, Object[], TargetSource)
(17)ProxyFactory.getProxy(ClassLoader)
(18)ProxyFactory(ProxyCreatorSupport).createAopProxy()
参考:https://www.douban.com/note/717482377/

<think>嗯,用户想了解AOP代理对象的生成时机及其原理。我需要先回忆一下Spring框架中AOP的相关知识。记得Spring的AOP是基于动态代理实现的,主要有两种方式:JDK动态代理和CGLIB。生成代理对象的时机应该是在Bean的生命周期中的某个阶段吧? 根据引用[3],提到Spring的AOP动态代理对象是在Bean生命周期的某个阶段创建的,可能有两种情况。用户的问题里也提到,很多人可能认为是第一种情况,但实际上还有另一种情况。这时候需要具体分析Bean的生命周期步骤。 Spring Bean的生命周期大致分为实例化、属性填充、初始化等阶段。AOP代理应该在Bean初始化之后生成,因为需要拦截方法调用。但具体是在初始化前还是后呢?可能是在Bean的后置处理器阶段处理的。比如,AbstractAutoProxyCreator是Spring用来生成代理的一个后置处理器,它会在Bean初始化之后应用代理。 再来看引用[1],AnnotationAwareAspectJAutoProxyCreator是处理AOP代理的处理器,属于BeanPostProcessor的一种。BeanPostProcessor的postProcessAfterInitialization方法会在Bean初始化之后被调用,所以代理对象可能是在这个时候生成的。 但引用[4]提到@Async注解可能导致循环依赖问题,因为Async切面的处理在后置处理器中执行,而其他如@Transactional在AbstractAutoProxyCreator处理循环依赖时使用getEarlyBeanReference暴露早期代理对象。这说明在存在循环依赖的情况下,代理对象的生成可能提前到实例化后的早期阶段,通过getEarlyBeanReference方法暴露,避免注入时的不一致。 所以,总结起来,AOP代理的生成时机有两种情况:正常情况下是在Bean初始化之后,由后置处理器生成;存在循环依赖时,可能在实例化后的早期阶段生成代理,以解决依赖问题。 接下来是原理部分。动态代理通过创建代理对象来包裹目标对象,代理对象拦截方法调用,在方法前后执行增强逻辑。JDK动态代理要求目标实现接口,而CGLIB通过继承生成子类代理。引用[2]提到代理对象持有被代理对象,这样在调用方法时可以委托给被代理对象,并在前后插入切面逻辑。 需要确保回答结构清晰,分点说明生成时机和原理,并引用提供的资料来支持观点。最后生成相关问题,可能涉及循环依赖、不同注解的处理差异、以及动态代理类型的选择等。</think>### AOP代理对象的生成时机及原理 #### **1. 生成时机** AOP代理对象的生成主要发生在Spring Bean的生命周期中,具体分为以下两种情况: - **正常情况**:在Bean初始化完成后,通过`BeanPostProcessor`的`postProcessAfterInitialization`方法生成代理对象。 此时,`AnnotationAwareAspectJAutoProxyCreator`(Spring AOP的核心后置处理器)会检查Bean是否需要被代理。若需要,则生成动态代理对象替换原始Bean[^1][^3]。 - **循环依赖场景**:当存在循环依赖时,代理对象可能在Bean实例化后的**早期阶段**(`getEarlyBeanReference`方法中)生成。 例如,`@Async`注解可能因代理对象生成时机不同导致循环依赖异常,而`@Transactional`等注解通过`AbstractAutoProxyCreator`提前暴露代理对象避免此问题[^4]。 --- #### **2. 核心原理** AOP代理通过**动态代理**技术实现,具体分为两类: - **JDK动态代理**:基于接口,为目标对象生成接口的代理类代理类通过`InvocationHandler`拦截方法调用,并在方法前后执行增强逻辑。 例如:`public class Proxy implements TargetInterface { ... }`。 - **CGLIB代理**:基于继承,为目标类生成子类代理。通过重写父类方法实现拦截。 例如:`public class Target$$EnhancerBySpringCGLIB extends Target { ... }`[^2]。 **代理对象的作用**: - 持有被代理对象(目标对象)的引用,在方法调用时委托给目标对象执行核心逻辑。 - 在方法执行前后插入切面逻辑(如日志、事务等),实现非侵入式增强[^2][^3]。 --- #### **3. 关键流程示例** ```java // 1. 目标对象 public class UserService { public void saveUser() { /* 核心逻辑 */ } } // 2. 代理对象生成(简化示例) public class UserServiceProxy extends UserService { private UserService target; @Override public void saveUser() { // 前置增强(如@Before) System.out.println("开始事务"); // 调用目标方法 target.saveUser(); // 后置增强(如@After) System.out.println("提交事务"); } } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值