循环依赖 spring中将循环依赖处理分为了两种情况
构造器循环依赖 使用构造器注入构成循环依赖,这种方式无法进行解决,抛出了BeanCurrentlyInCreationException异常
在创建bean之前会进行检测
1 2 3 4 5 6 7 protected void beforeSingletonCreation (String beanName) { if (!this .inCreationCheckExclusions.contains(beanName) && !this .singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } }
在创建bean之后会进行移除
1 2 3 4 5 protected void afterSingletonCreation (String beanName) { if (!this .inCreationCheckExclusions.contains(beanName) && !this .singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation" ); } }
以TestA和TestB为例,由于构造器造成了循环依赖,所以在进行实例化TestA时(实例化TestA之前执行了beforeSingletonCreation方法,此时singletonsCurrentlyInCreation中添加TestA),需要TestB实例,所以需要实例化TestB(实例化TestB之前执行了beforeSingletonCreation方法,此时singletonsCurrentlyInCreation中添加TestB),然后在进行TestB时需要TestA实例,又需要进行实例化TestA,但是执行beforeSingletonCreation方法时,singletonsCurrentlyInCreation中已存在TestA,所以会抛出BeanCurrentlyInCreationException异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class TestA { private TestB testB; public TestA (TestB testB) { this .testB = testB; } } public class TestB { private TestA testA; public TestB (TestA testA) { this .testA = testA; } }
setter循环依赖 对于setter注入造成的循环依赖,spring采用的是提前暴露刚完成的构造器实例化但未完成setter方法注入的bean来实现的,而且只能解决单例作用域的bean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 protected Object getSingleton (String beanName, boolean allowEarlyReference) { Object singletonObject = this .singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this .singletonObjects) { singletonObject = this .earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this .singletonFactories.get(beanName); if (singletonFactory != null ) { singletonObject = singletonFactory.getObject(); this .earlySingletonObjects.put(beanName, singletonObject); this .singletonFactories.remove(beanName); } } } } return (singletonObject != NULL_OBJECT ? singletonObject : null ); } sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject () throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } } }); if (instanceWrapper == null ) { instanceWrapper = createBeanInstance(beanName, mbd, args); } addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject () throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); protected void addSingletonFactory (String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null" ); synchronized (this .singletonObjects) { if (!this .singletonObjects.containsKey(beanName)) { this .singletonFactories.put(beanName, singletonFactory); this .earlySingletonObjects.remove(beanName); this .registeredSingletons.add(beanName); } } } populateBean(beanName, mbd, instanceWrapper); protected void addSingleton (String beanName, Object singletonObject) { synchronized (this .singletonObjects) { this .singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT)); this .singletonFactories.remove(beanName); this .earlySingletonObjects.remove(beanName); this .registeredSingletons.add(beanName); } }
以TestA和TestB为例,创建单例TestA时,使用无参构造器进行创建,并将实例化的bean放入一个ObjectFactory中,存入到singletonFactories,用于返回提前暴露的bean,然后进行setter方法来注入TestB,此时还没有TestB,来创建单例TestB,使用无参构造器进行创建,并将实例化的bean放入一个ObjectFactory中,存入到singletonFactories,用于返回提前暴露的bean,然后进行setter来注入TestA,从ObjectFactory.getObject可以获取到testA,完成了TestB#setTestA方法,之后继续走TestA的逻辑,从而完成TestA#setTestB方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class TestA { private TestB testB; public TestB getTestB () { return testB; } public void setTestB (TestB testB) { this .testB = testB; } } public class TestB { private TestA testA; public TestA getTestA () { return testA; } public void setTestA (TestA testA) { this .testA = testA; } }
总结一下
一级缓存 singletonObjects 存放的是完全创建好的单例Bean
二级缓存 earlySingletonObjects 存放的是完成实例化,但是还未进行属性注入的对象
三级缓存 singletonFactories 提前暴露的一个单例工厂,二级缓存的对象就是通过这个单例工厂创建的
有个疑问 看上去好像二级缓存就可以解决循环依赖了,三级缓存的对象工厂的意义是什么呢?
来看一下不管有没有循环依赖,都会创建好一个对象,然后放入到三级缓存中
1 2 3 4 5 6 7 addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject () throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } });
只有调用三级缓存中的ObjectFactory.getObject()才会拿到对象,看一下getEarlyBeanReference干了什么吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 protected Object getEarlyBeanReference (String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); if (exposedObject == null ) { return null ; } } } } return exposedObject; }
也就是做了个延迟代理的作用,在二级缓存里存放的其实是代理过的对象