Spring框架自己很是庞大,源码阅读能够从Spring IOC容器的实现开始一点点了解。然而即使是IOC容器,代码仍然是很是多,短期内所有精读完并不现实
本文分析比较浅,而完整的IOC建立bean其实是很是复杂的。本文对于BeanDefinition的加载解析,bean实例化的反射调用细节不做介绍,仅以较为粗略的角度来大致感觉IOC容器建立bean的过程。java
本文涉及的Spring源码版本为4.3.5.RELEASE。spring
下面就抛出几个想要了解的问题,也是本文介绍所要围绕的关键点。缓存
org.springframework.beans.factory.BeanFactory是Spring的Bean容器的一个很是基本的接口,位于spring-beans模块。它包括了各类getBean方法,如经过名称、类型、参数等,试图从Bean容器中返回一个Bean实例。还包括诸如containsBean, isSingleton, isPrototype等方法判断Bean容器中是否存在某个Bean或是判断Bean是否为单例/原型等等。app
能够看到BeanFactory向下主要有三条继承路线框架
org.springframework.context.ApplicationContext是Spring上下文的底层接口,位于spring-context模块。它能够视做是Spring IOC容器的一种高级形式,也是咱们用Spring企业开发时必然会用到的接口,它含有许多面向框架的特性,也对应用环境做了适配。ide
从上面的图中,咱们能够看到ApplicationContext做为BeanFactory的子接口,与BeanFactory之间也是经过HierarchicalBeanFactory与ListableBeanFactory桥接的。
ApplicationContext接口,继承了MessageSource, ResourceLoader, ApplicationEventPublisher接口,以BeanFactory为主线添加了许多高级容器特性。工具
搞清楚整个Spring IOC容器建立Bean的过程,对于阅读源码的效率会有很大的提高。
下面梳理一下整个过程:源码分析
完整来讲,IOC容器的初始化过程当中作了在容器中创建BeanDefinition的数据映射。以后全部的依赖的注入都依托于已经存在的BeanDefinition,限于篇幅,此处略去对BeanDefinition的创建做介绍。直接从上下文的getBean开始看起。post
在AbstractApplicationContext抽象类中有一个getBeanFactory方法用于返回一个ConfigurableListableBeanFactory,全部BeanFactory接口的方法实际上都委托给子类内部的ConfigurableListableBeanFactory实现。ui
咱们以AnnotationConfigApplicationContext,它在被构造时,内部的beanFactory其实是由父类GenericApplicationContext来初始化一个DefaultListableBeanFactory的。
所以咱们看某个bean是如何被加载的能够从DefaultListableBeanFactory的getBean方法看起,对于DefaultListableBeanFactory而言那些getBean方法实际上在AbstractBeanFactory这一层就都已经实现了,而且都委托给了AbstractBeanFactory#doGetBean。下面就来看一下doGetBean方法。
protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; /* * 尝试从缓存中拿取一个bean实例。 * Spring会在Bean还没彻底初始化完毕的前,经过一个ObjectFactory提早暴露出bean实例,这样为解决循环依赖提供了遍历。 */ Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } // 对FactoryBean的状况进行特殊处理。 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // 若是正在建立的bean为原型而且已经正在建立,这种循环依赖是没法解决的,要抛出异常。 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // 若是该beanFactory中不包含要建立bean的beanDefinition,则尝试从父beanFactory中寻找。 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { String nameToLookup = originalBeanName(name); if (args != null) { return (T) parentBeanFactory.getBean(nameToLookup, args); } else { return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // 有些bean是有depends-on/@DependsOn的,须要先初始化这些依赖。 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); getBean(dep); } } // 建立单例bean。 if (mbd.isSingleton()) { /* * 调用父类DefaultSingletonBeanRegistry的getSingleton,具体建立bean的工做实际上仍然是 * 回调参数中传递的ObjectFactory#getObject方法,而createBean其实是子类AbstractAutowireCapableBeanFactory实现的。 */ 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; } } }); // 对FactoryBean的状况进行特殊处理。 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } // 建立原型bean。 else if (mbd.isPrototype()) { Object prototypeInstance = null; try { // 前置处理,维护prototypesCurrentlyInCreation,加入当前bean记录。 beforePrototypeCreation(beanName); // 委托给子类AbstractAutowireCapableBeanFactory来完成具体的建立bean工做。 prototypeInstance = createBean(beanName, mbd, args); } finally { // 后置处理,维护prototypesCurrentlyInCreation信息,删除当前bean记录。 afterPrototypeCreation(beanName); } // 对FactoryBean的状况进行特殊处理。 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // 到这里一个bean就已经建立完了,最后一步检查类型,若是不匹配会尝试转换。 if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { try { return getTypeConverter().convertIfNecessary(bean, requiredType); } catch (TypeMismatchException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
上面针对AbstractBeanFactory#doGetBean方法进行了源码分析,从中咱们能够看出它主要会干这几件事情:
咱们通常比较关心的就是单例bean和原型bean的建立。
在获取单例bean时doGetBean方法会调用父类DefaultSingletonBeanRegistry#getSingleton。能够把DefaultSingletonBeanRegistry看成一个“单例bean桶”,由于它确实就是一个用来存放单例bean的桶。可是这个桶自己不关心bean到底该怎么建立,因此对于桶里尚未的bean,它将建立bean的职责经过回调ObjectFactory#getObject来完成,而AbstractBeanFactory中传递给getSingleton方法的ObjectFactory#getObject的具体实现是调用createBean,这个方法是真正建立并初始化bean的方法,由子类AbstractAutowireCapableBeanFactory完成。
对于获取原型bean则简单多了,不用关心放到桶里缓存的事情,直接调用createBean建立就是了。
因此咱们接下来经过AbstractAutowireCapableBeanFactory来看一下一个Bean具体是如何建立并初始化的。
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { /* * 在对象被实例化前,这里有一个短路逻辑,会调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation。 * 若是存在某个InstantiationAwareBeanPostProcessor的调用结果不为null,则造成了短路,接下来调用BeanPostProcessor#postProcessAfterInitialization。 * * 实际上,通常Spring里默认就LazyInitTargetSourceCreator和QuickTargetSourceCreator可能会使得这里的短路生效。 * 大部分状况AOP仍是在bean被正常实例化后经过调用postProcessAfterInitialization实现的。 */ Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } // 建立bean的主要方法。 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
从上面能够看到AbstractAutowireCapableBeanFactory#createBean是建立bean的主要入口方法,但仍然不是最主要在“干活”的方法。继续向下看doCreateBean
方法。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { // 尝试从factoryBean缓存中获取。 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 建立bean实例。 instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } /* * Spring为了解决单例bean的循环引用问题,会在bean尚未彻底初始化完毕前经过添加singletonFactory * 使得其它bean能够拿到某个bean的实例引用。 */ boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // 接下去初始化bean。 Object exposedObject = bean; try { // 填充bean中的属性。 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { /* * 调用初始化方法,好比: * 1. 各类aware回调 * 2. 调用BeanPostProcessor#postProcessBeforeInitialization * 3. 调用InitializingBean#afterPropertiesSet, xml中的init-method * 4. 调用BeanPostProcessor#postProcessAfterInitialization */ exposedObject = initializeBean(beanName, exposedObject, mbd); } } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); /* * 上面的getSingleton第二个参数为false表示不会主动触发early reference的建立。 * 因此此处earlySingletonReference只有在bean建立过程当中发现有别的bean与当前bean有循环依赖才不为空。 */ if (earlySingletonReference != null) { /* * 若是当前bean调用initializeBean没有加强原始bean实例,则取earlySingletonReference。 * * 举例: * BeanA与BeanB互相依赖。Srping先建立BeanA,再建立BeanB。 * BeanA经过addSingletonFactory暴露了获取BeanA引用的途径。 * * 在populateBean的时候须要注入BeanB,而BeanB又须要注入BeanA, * 则在获取BeanA时会调用原先BeanA暴露的ObjectFactory,继而使得earlySingletonObjects中加入了BeanA引用。 * * 回到BeanA的建立过程,走到此步时,发现initializeBean没有加强原始bean实例, * 则须要取其它循环依赖bean拿BeanA时在registry留下的结果(原始bean通过SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference回调)。 */ if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { // 获取当前bean依赖的其它bean。 String[] dependentBeans = getDependentBeans(beanName); // 过滤筛选出真正依赖的bean。 Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } /* * 举例: * BeanA与BeanB互相依赖。Srping先建立BeanA,再建立BeanB。 * BeanA的建立走到这里时会抛出异常。 * * 缘由是上面的exposedObject != bean说明initializeBean方法的调用加强了原始的BeanA。 * 而BeanB中注入的BeanA极可能是原始beanA(可能会有SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference回调, * 也就是BeanB中注入的BeanA不是此处BeanA的最终版exposedObject。 */ 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."); } } } } try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
不是全部的循环依赖Spring都可以解决的。
对于最简单的状况,bean为单例,且使用Autowired或者setter注入,Spring是能够解决这样的循环依赖的。经过上面的代码中咱们能够看出,在一个Bean实例化后,会调用addSingletonFactory方法,在IOC容器中经过一个ObjectFactory暴露出能够获取还未彻底初始化完毕的bean引用。若存在循环依赖,则依赖的bean能够在调用getBean时经过getSingleton方法获取到循环依赖的bean。
可是Spring是不容许出现原型环的,举例来讲,BeanA和BeanB循环依赖且scope都为prototype。由于prototype的bean,不会触发addSingletonFactory,即每次get这样的bean都会新建立一个。因此建立BeanA须要注入一个BeanB,而这个BeanB又须要注入一个新的BeanA,这样的循环依赖是没办法解决的。Spring会判断当前bean是不是prototype而且已经在建立中,而后抛出异常。
Spring中有不少XXXAware接口,从字面意思上很容易理解:就是bean可以“感知”XXX。一般这些接口的方法都是setXXX。在项目里作一个工具类实现ApplicationContextAware接口,里面能够塞一个ApplicationContext实例到静态域中,在代码中就能够很方便获取到Spring上下文进行一些操做。
那么Spring对于这些Aware接口是在哪一步调用的呢?答案其实在上面的源码分析中已经提到。在AbstractAutowireCapableBeanFactory#initializeBean方法中,Spring默认会对实现BeanNameAware, BeanClassLoaderAware, BeanFactoryAware进行回调,为它们注入beanName, classLoader, beanFactory等。
而对于更多的一些扩展,Spring基于那些processor实现了很强的可拓展性与可插拔性。好比咱们很是熟悉的ApplicationContextAware接口其实是经过ApplicationContextAwareProcessor来实际调用的,它继承了BeanPostProcessor,其中postProcessBeforeInitialization方法中会对EnvironmentAware, EmbeddedValueResolverAware, ApplicationContextAware等等一系列Aware接口的子类Bean进行回调,为其注入相关资源。
那么ApplicationContextAwareProcessor是何时出如今BeanPostProcessor集合中的呢?在AbstractApplicationContext#prepareBeanFactory方法中,Spring有以下代码:
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
也就是当Spring上下文在初始化prepareBeanFactory的时候就已经添加了ApplicationContextAwareProcessor。