AbstractBeanFactory#doGetBean
源码解析首先看AbstractBeanFactory
中doGetBean
方法,java
protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); ... // 调用getSingleton方法获取到实例 sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } } }); }
上面第一个getSingleton
返回的一个单例,spring检查系统内存中该bean是否建立,可是这里很显然,咱们的单例尚未开始建立,因此这里返回null。
注意:这个方法很重要,是循环依赖核心,后面会用到
继续往下看,这里又会调用一个getSingleton
方法,这里会传入一个ObjectFactory
,里面只有一个getObject
方法,返回建立的bean实例。
createBean
方法源码解析
该方法源码及注释以下:web
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while the singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } beforeSingletonCreation(beanName); ... try { // 调用getObject,建立bean singletonObject = singletonFactory.getObject(); newSingleton = true; } ... finally { afterSingletonCreation(beanName); } if (newSingleton) { // 将建立的bean添加到spring集合中 addSingleton(beanName, singletonObject); } } return (singletonObject != NULL_OBJECT ? singletonObject : null); } } 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); } }
singletonObjects:缓存已完成的bean实例
singletonFactories:缓存每一个bean以及建立该bean的实例工厂ObjectFactory
earlySingletonObjects:缓存早期建立的bean,早期也就是该bean已经完成实例化,可是经过IoC注入的依赖还没注入。简单的说就是只调用了构造器方法,未调用任何setter方法。
registeredSingletons:缓存注册在spring容器中的bean,是一个set集合,只记录bean名字spring
doCreateBean
源码解析
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { ... // 首先建立bean实例 createBeanInstance(beanName, mbd, args); final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); mbd.resolvedTargetType = beanType; ... // 早期缓存单例 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { // 将bean与该bean的早期对象引用添加到map中 addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { // 管理建立的bean属性,也就是对使用@Autowire类进行设值处理 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { // 若是该Bean实现了BeanNameAware或BeanFactoryAware等接口,调用对应方法对bean进行初始化 exposedObject = initializeBean(beanName, exposedObject, mbd); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
spring在调用createBeanInstance
方法时会判断当前这个bean构造方法上是否存在注入的类,若是存在则调用autowireConstructor
建立实例,
不然调用instantiateBean
.instantiateBean
比较简单,一种是经过CGLIB进行动态代理,若是目标类scope为prototype
或有@Lookup
注解标识,
固然大部分仍是经过java反射来建立(Class.forName(xxx))。下一步调用populateBean
,若是spring发现某些属性是注进来的,对这些属性进行
赋值时须要初始化这些类,把引用赋给当前bean的类变量,这里举个例子:缓存
@Component class A { @Autowire private B b; } @Component class B { @Autowire private A a; }
spring在对A进行doCreateBean
会经历createBeanInstance
-> populateBean
-> initializeBean
这三个核心阶段。
调用createBeanInstance
也至关于执行new A()
,这时咱们能够获取到A这个类的引用了。第二步执行populateBean
,对A
中的属性b
进行赋值。
spring这时发现B
还没开始初始化,因而开始初始化B
,仍然从上面doGetBean
步骤开始,固然走到最后会遇到A
同样的问题,对属性a
进行赋值时,
会调用getBean
获取A
对象的引用,程序又来到了上面的doGetBean
方法,可是这里再次执行getSingleton
方法时,会有神奇的效果:app
protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 因为singletonObjects里面存放的是建立且实例化完成的bean,而这里因为A/B均有部分属性未初始化完成,因此还不在singletonObjects集合中 Object singletonObject = this.singletonObjects.get(beanName); // 该bean当前正在建立过程当中,这里isSingletonCurrentlyInCreation返回的也是true if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { // 因为前面doCreateBean中调用了addSingletonFactory,他会将实例化后的bean添加到registeredSingletons中, // 将对应的ObjectFactory添加到singletonFactories集合中,并从earlySingletonObjects中将该bean移除,因此这里返回null singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { // 获取到该bean的ObjectFactory,经过该factory获取到该bean的earlySingletonObject,也就是早期对象 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); }
这里对B
进行初始化并调用populateBean
时,对A
对象的循环引用问题就解决了,B
对象正常生成后,A
也就执行populateBean
下一步initializeBean
了。
到此,spring的循环依赖问题就解决完了。ide
前面咱们讲解了spring如何解决循环依赖及原理,那是否是spring能够解决一切循环依赖呢?答案固然是错的。先看下面一个demo:svg
@Component class A { private B b; @Autowire public A(B b) { this.b = b; } } @Component class B { private A a; @Autowire public B(A a) { this.a = a; } }
这里在建立A实例过程当中,也就是createBeanInstance
时,spring发现构造方法上有@Autowire
注解,那么会先执行注入的bean初始化,如上面
在生成A
实例时,发现A
上有依赖B
,那么会执行B
的依赖注入,在getBean(b)
时,发现B
仍未初始化,那么执行B
的初始化,当发现B
有依赖A
且spring的earlySingletonObjects
中并无A
的引用,就会产生循环依赖报错。ui