上文中咱们学习了bean加载的整个过程,咱们知道从spring容器中获取单例bean时会先从缓存尝试获取,若是缓存中不存在已经加载的单例bean就须要从头开始bean的建立,而bean的建立过程是很是复杂的,本文就开始研究bean加载这部分的源码。html
在Spring中bean加载的逻辑是在getSingleton的重载方法中实现的:spring
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "'beanName' must not be null"); // 全局变量须要同步 synchronized (this.singletonObjects) { // 首先检查对应的bean是否已经加载过,由于singleton模式就是复用已建立的bean,因此这一步是必须的 Object singletonObject = this.singletonObjects.get(beanName); // 若是为空才能够进行singleton的bean的初始化 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!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } beforeSingletonCreation(beanName); boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<Exception>(); } try { // 初始化bean singletonObject = singletonFactory.getObject(); } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName); } // 加入缓存 addSingleton(beanName, singletonObject); } return (singletonObject != NULL_OBJECT ? singletonObject : null); } }
这里建立bean使用了回调方法(实际上是匿名内部类),真正获取单例bean的方法其实现逻辑是在ObjectFactory类型的实例singletonFactory的getObject()方法中实现的。Spring在建立单例先后还有一些准备及处理操做,包括以下内容:缓存
归纳起来主要有下面几方面:架构
在beforeSingletonCreation()方法中有一个很重要的操做:记录加载状态,也就是经过this.singletonsCurrentlyInCreation.add(beanName)将当前正要建立的bean记录在缓存中,这样即可以对循环依赖进行检测。app
protected void beforeSingletonCreation(String beanName) { if (!this.inCreationCheckExclusions.containsKey(beanName) && this.singletonsCurrentlyInCreation.put(beanName, Boolean.TRUE) != null) { throw new BeanCurrentlyInCreationException(beanName); } }
同记录加载状态类似,当bean加载结束后须要移除缓存中记录的该bean的加载状态记录:ide
protected void afterSingletonCreation(String beanName) { if (!this.inCreationCheckExclusions.containsKey(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); } }
将结果记录至缓存并删除加载bean过程当中所记录的各类辅助状态:函数
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); } }
虽然前面已经分析了加载bean的逻辑架构,但如今并无开始对bean加载功能的探索,前面提到过,bean加载逻辑实际上是在匿名内部类ObjectFactory的getObject()方法中定义的:post
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { 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; } } });
ObjectFactory的核心部分其实只是调用了createBean()方法,也就是建立的bean的逻辑都在这里面,因此咱们还需继续寻找真理。学习
跟踪了这么多Spring代码,也发现了一些规律:一个真正干活的函数实际上是以do开头的,好比doGetObjectFromFactoryBean(),而容易给咱们带来错觉的函数,好比getObjectFromFactoryBean(),其实只是从全局角度作了一些统筹工做。这个规则对于createBean()也不例外,咱们就来看一下其中作了哪些准备工做:this
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } // 根据设置的class属性或者根据className来解析Class resolveBeanClass(mbd, beanName); // 验证及准备覆盖的方法 try { mbd.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // 给BeanPostProcessors一个机会返回代理的机会来替代真正的实例 Object bean = resolveBeforeInstantiation(beanName, mbd); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } Object beanInstance = doCreateBean(beanName, mbd, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
总结一下具体步骤:
在Spring的配置里面是没有诸如override-method之类的配置,那为何还须要有override属性进行标记及验证这一步呢?这是由于在Spring配置中存在lookup-method和replace-method的,而这两个配置的加载其实就是将配置统一存放在BeadDefinition中的methodOverrides属性里,而这步操做就是针对这两个配置的。
来看一下这几个主要的步骤:
这部分的逻辑是在AbstractBeanDefinition类的prepareMethodOverrides方法中:
public void prepareMethodOverrides() throws BeanDefinitionValidationException { // Check that lookup methods exists. MethodOverrides methodOverrides = getMethodOverrides(); if (!methodOverrides.isEmpty()) { for (MethodOverride mo : methodOverrides.getOverrides()) { prepareMethodOverride(mo); } } } protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException { // 获取对应类中对应方法名的个数 int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName()); if (count == 0) { throw new BeanDefinitionValidationException( "Invalid method override: no method with name '" + mo.getMethodName() + "' on class [" + getBeanClassName() + "]"); } else if (count == 1) { // 标记MethodOverride暂未被覆盖,避免参数类型检查的开销 mo.setOverloaded(false); } }
在Spring配置中存在lookup-method和replace-method两个配置功能,而这两个配置的加载其实就是将配置统一存放在BeanDefinition中的methodOverrides属性里,这两个功能实现原理实际上是在bean实例化的时候若是检测到存在methodOverrides属性,会动态地为当前bean生成代理并使用对应的拦截器为bean作加强处理,这部分在建立bean部分会作详细解析。
可是这里要提到的是,对于方法的匹配来说,若是一个类中存在若干个重载方法,那么,在函数调用及加强的时候还须要根据参数类型进行匹配,来最终确认当前调用的究竟是哪一个函数。可是,Spring将一部分匹配工做在这里完成了,若是当前类中的方法只有一个,那么就设置该方法没有被重载,这样在后续调用的时候即可以直接使用找到的方法,而不须要进行方法的参数匹配验证了,并且还能够提早对方法存在性进行验证,正可谓一石二鸟,这部分须要结合后面的逻辑来理解,如今不理解能够先忽略。
在真正调用doCreate方法建立bean实例前使用了方法resolveBeforeInstantiation()对BeanDefinition中的属性作一些前置处理。这里不管其中是否有相应的逻辑实现,咱们均可以理解,由于真正逻辑实现先后留有处理函数也是可扩展的一种体现。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
这里最重要的无疑是两个方法applyBeanPostProcessorsBeforeInstantiation以及applyBeanPostProcessorsAfterInitialization,其实现很是简单,无非是对后处理器中全部InstantiationAwareBeanPostProcessor类型的后处理器进行postProcessBeforeInstantiation方法和BeanPostProcessor的postProcessAfterInitialization方法的调用。
实例化前的后处理器应用
bean的实例化前调用,也就是将AbstractBeanDefinition转换为BeanWrapper前的处理,这至关于给子类一个修改BeanDefinition的机会,也就是说当程序通过这个方法以后,bean可能已经不是咱们认为的bean了,有多是一个通过处理的代理bean,多是经过cglib生成也多是经过其余技术生成的,这个在后面涉及到AOP时会讲到,如今咱们只须要知道,在bean的实例化前会调用后处理器的方法进行处理:
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }
实例化后的后处理器应用
Spring中的规则是在bean初始化后尽量保证将注册的后处理器的postProcessAfterInitialization方法应用到该bean中,由于若是返回的bean不为空,那么便不会再次经历普通bean的建立过程,因此只能在这里应用后处理器的postProcessAfterInitialization方法。
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null) { return result; } } return result; }
这里还有一点很重要,在该函数中还有一个短路判断,这个很关键:
if(bean != null) { return bean; }
当通过前置处理后返回的结果若是不为空,那么会直接略事后续的Bean建立而直接返回,这个地方很容易被忽视,可是却起着相当重要的做用,咱们熟知的AOP功能就是基于这里的判断的,后面关于AOP的文章中也会涉及到。
当经历过resolveBeforeInstantiation()方法后,若是建立了代理或者重写了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法并在方法postProcessBeforeInstantiation()中改变了bean,则直接返回就能够了,不然就须要进行常规bean的建立,这是在doCreateBean中完成的:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { 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); // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { // 应用MergedBeanDefinitionPostProcessor applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } // 是否须要提前曝光:单例&容许循环依赖&当前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"); } // 为避免后期循环依赖,能够在bean初始化完成前将建立实例的ObjectFactory加入工厂 addSingletonFactory(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { // 对bean再一次依赖引用,主要应用SmartInstantiationAwareBeanPostProcessor // 其中咱们熟知的AOP就是在这里将advice动态织入bean中,若没有则直接返回bean,不作任何处理 return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { // 对bean进行填充,将各个属性值注入,其中,可能存在依赖于其余bean的属性,则会递归初始依赖bean populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { // 调用初始化方法,好比init-method 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); // earlySingletonReference只有在检测到有循环依赖的状况下才会不为空 if (earlySingletonReference != null) { // 若是exposedObject没有在初始化方法中被改变,也就是没有被加强 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); } } // 由于bean建立后其所依赖的bean必定是已经建立的, // actualDependentBeans不为空则表示当前bean建立后其依赖的bean却没有所有 // 建立完,也就是说存在循环依赖 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 { // 根据scope注册bean registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
咱们这里只简单看看整个函数的概要思路,各个部分详细逻辑留待后文分析:
1. 若是是单例则须要首先清除缓存。
2. 建立bean实例,即将BeanDefinition转换为BeanWrapper。
转换是一个复杂的过程,可是咱们仍是能够尝试归纳大体的功能,以下所示。
3. MergedBeanDefinitionPostProcessor的应用。
bean合并后的处理,Autowired注解正是经过此方法实现诸如类型的解析。
4. 依赖处理
在Spring会有循环依赖的状况,例如,当A中含有B的属性,而B中又含有A的属性时就会构成一个循环依赖,此时若是A和B都是单例,那么在Spring中的处理方式就是当建立B的时候,涉及自动注入A的步骤时,并非直接去再次建立A,而是经过放入缓存中的ObjectFactory来建立实例,这样就解决了循环依赖问题。
5. 属性填充。将全部的属性填充至bean的实例中。
6. 循环依赖检查。
Spring中只在单例下才会解决循环依赖,而对于prototype的bean,Spring没有好的解决办法,惟一要作的就是抛出异常。在这个步骤里面会检测已经加载的bean是否已经出现了依赖循环,并判断是否须要抛出异常。
7. 注册DisposableBean
若是配置了destroy-method,这里须要注册以便于在销毁时候调用。
8. 完成建立并返回。
本文先从全局角度分析了bean建立的整个流程,而后着重分析了Spring在bean建立以前所作的一些准备工做,包括override属性处理、实例化先后对后处理器的应用,这些都只是一些全局性的统筹工做,以后又看了一下bean建立的实际过程,后面就要开始详细分析bean的建立过程了,这个才是真正爬坡的开始。