当A对象和B对象发生循环依赖时,B对象会在什么时候创建代理对象?
最近几天看spring源码 产生了一个疑惑:当A对象和B对象发生循环依赖,A对象被B对象注入时,会将A对象从三级缓存中取出来并调用其方法,但是A对象的不完整对象创建完成后,B对象也就创建完成了,那么B对象是在什么时候判断是否需要生成代理对象的呢?
结论:在这种情况下,spring不会判断B对象是否需要生成代理对象,如果使用了@EnableAspectJAutoProxy注解,会在BeanPostProcessor的后置处理器里进行处理
###后附spring生命周期及spring三级缓存的流程图###
// 查找缓存取得Bean Object sharedInstance = getSingleton(beanName);
// 此处初期调用 allowEarlyReference传入值为true protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 从一级缓存中查找当前Bean Object singletonObject = this.singletonObjects.get(beanName); // 判断当前bean是否正在创建中 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { // 从二级缓存中查找当前Bean singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { synchronized (this.singletonObjects) { // 加锁再次尝试 singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { // 从三级缓存中查找当前Bean ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { // 调用三级缓存lambda表达式中的方法 singletonObject = singletonFactory.getObject(); // 放入二级缓存 this.earlySingletonObjects.put(beanName, singletonObject); // 从三级缓存中移除 this.singletonFactories.remove(beanName); } } } } } } return singletonObject; }
// 添加到三级缓存 beanName作为key lambda表达式作为value addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// 判断是否需要AOP代理 protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { // 原始对象 Object exposedObject = bean; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) { // 生成代理对象 exposedObject = bp.getEarlyBeanReference(exposedObject, beanName); } } return exposedObject; }
带着这个疑惑,我进行了数次debug,最终发现它确实是没有执行该逻辑的
我加上@EnableAspectJAutoProxy注解一次次debug,最终发现B对象的代理对象生成逻辑是在BeanPostProcessor的后置方法applyBeanPostProcessorsAfterInitialization中进行处理的 在这之前B一直都是原始对象
@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; // 获取所有的BeanPostProcessor for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
原来,@EnableAspectJAutoProxy注解中导入了一个类:AspectJAutoProxyRegistrar
它会将AnnotationAwareAspectJAutoProxyCreator注册到 BeanDefinitionRegistry中
因此,spring确实是对B对象没有进行AOP代理对象处理,是由AOP在后置处理器中进行处理的
最后放出最近整理的spring生命周期及spring三级缓存的流程图
spring生命周期流程图
spring三级缓存流程图