前边我们吭哧吭哧的说了一堆bean加载过程中可能的扩展方式,在本节中,我们就从源码的角度详细分析下bean的加载过程。
需要提前说明的是,为了便于阅读以及限于篇幅,我展示的代码可能会对源码做出了部分删除省略,当然,相应处都会标记,如果感兴趣的话,可以自己对比源码阅读。
Account account=(Account) beanFactory.getBean("account"); 复制代码
我们可以通过beanFactory的getBean()方法来获得需要的bean
public Object getBean(String name) throws BeansException { return this.doGetBean(name, (Class)null, (Object[])null, false); } 复制代码
接着调用doGetBean
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { String beanName = this.transformedBeanName(name); // 尝试获取单例Bean,注意循环依赖问题 Object sharedInstance = this.getSingleton(beanName); Object bean; // sharedInstance不为null即此时是单例模式且缓存中已存在bean,直接从缓存中获取bean if (sharedInstance != null && args == null) { if (this.logger.isTraceEnabled()) { if (this.isSingletonCurrentlyInCreation(beanName)) { this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null); // 此时是原型模式或者单例模式但是缓存中还不存在bean } else { // 此时存在循环依赖,然而原型模式直接抛出异常,这个异常名字也很好理解, bean正在创建状态 if (this.isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } BeanFactory parentBeanFactory = this.getParentBeanFactory(); // 从当前加载的配置中找不到 beanname,此时递归去parentFactory查找 if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) { String nameToLookup = this.originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); } if (args != null) { return parentBeanFactory.getBean(nameToLookup, args); } if (requiredType != null) { return parentBeanFactory.getBean(nameToLookup, requiredType); } return parentBeanFactory.getBean(nameToLookup); } if (!typeCheckOnly) { this.markBeanAsCreated(beanName); } try { RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName); this.checkMergedBeanDefinition(mbd, beanName, args); String[] dependsOn = mbd.getDependsOn(); String[] var11; // 递归实例化依赖的bean if (dependsOn != null) { var11 = dependsOn; int var12 = dependsOn.length; for(int var13 = 0; var13 < var12; ++var13) { String dep = var11[var13]; if (this.isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } this.registerDependentBean(dep, beanName); try { this.getBean(dep); } catch (NoSuchBeanDefinitionException var24) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24); } } } // 单例模式,此时需要我们去从头创建bean if (mbd.isSingleton()) { sharedInstance = this.getSingleton(beanName, () -> { try { return this.createBean(beanName, mbd, args); } catch (BeansException var5) { this.destroySingleton(beanName); throw var5; } }); bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd); // 原型模式 } else if (mbd.isPrototype()) { var11 = null; Object prototypeInstance; try { this.beforePrototypeCreation(beanName); prototypeInstance = this.createBean(beanName, mbd, args); } finally { this.afterPrototypeCreation(beanName); } bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); // 别的Scope的处理情况 } else { // something } } catch (BeansException var26) { this.cleanupAfterBeanCreationFailure(beanName); throw var26; } } // 检查需要的类型是否符合bean的实际类型 // some code here return bean; } 复制代码
这个代码相当长,我也只是在关键点做了些必要的注释,一次性看不懂没关系,先往后看
首先理一下:
Object sharedInstance = this.getSingleton(beanName); public Object getSingleton(String beanName) { return this.getSingleton(beanName, true); } protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 检查缓存中是否有bean, singletonObjects是个Map<beanName,beanInstance> Object singletonObject = this.singletonObjects.get(beanName); // 缓存中没有且该bean正处于创建状态 if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) { // 锁定全局变量 synchronized(this.singletonObjects) { // earlySingletonObjects 放置用于提前曝光的ObjectFactory,该ObjecFactory可生成对应bean singletonObject = this.earlySingletonObjects.get(beanName); // singletonObject 若不为空说明此时正在加载,直接返回即可 // 某些方法需要提前初始化时候会调用 addSingletonFactory 将对应ObjectFactory 存入 singletonFactories if (singletonObject == null && allowEarlyReference) { // singletonFactories是个Map<beanName,ObjectFactory> ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); // 记录在 earlySingletonObjects,同时清除 singletonFactories 中的记录,二者互斥 this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; } 复制代码
如果当前是第一次来获取创建中的实例的话,需要去singletonFactory获取ObjectFactory,后续就可以不用这么麻烦,直接从earlySingletonObjects中获取,当实例创建完成后,就更简单了,直接从 singletonObjecs中获取。如果你现在不太明白这段话,往后读吧,一会儿回头来看就懂了。
我们知道Spring可以很方便实现bean实例的注入,比如我们想要A a,结果A中有个B类的实例,所以Spring就需要去找到B的实例来注入,结果B中又有一个A a的属性,Spring又要去找A的实例,得,问题又回到原点,这就是循环依赖
@Component public class B { @Autowired A a; public B(A a){ this.a=a; } public void setA(A a) { this.a = a; } } 复制代码
@Component public class A { @Autowired B b; public void setB(B b) { this.b = b; } public A(B b){ this.b=b; } } 复制代码
@RunWith(SpringRunner.class) @SpringBootTest(classes = SpringdemoApplication.class) public class UserTest{ @Test public void tt(){ } } 复制代码
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException 复制代码
这就是一个很典型的循环依赖,可以看到抛出BeanCurrentlyInCreationException,即bean正在创建中。正如我们上边所说A中需要B,去创建B的实例,结果发现B中需要A,去找A发现A还在创建中,抛出异常。
解决方案很简单,去掉有参构造器,只保留setter。这样的话,Spring会首先由ObjectFactory得到一个刚初始化还没填充属性的A的实例,接着A需要B的实例,Spring去创建B的实例的过程,再接着B中需要A的实例,就把刚那个A的实例拿过来,注意B中的A的地址和刚刚那个A地址一样,所以后续填充完A的属性后,B中的A也就有了属性,看不太懂还是没关系,继续看,最后回来看。
原型模式中因为spring不会缓存bean,所以无法做到提前暴露,也因此无法解决循环依赖
好了,说完循环依赖我们再回归正题,
如果能得到不为空的singletonObject,紧接着来到getObjectForBeanInstance ,我们前边第一节讲过的FactoryBean派上用场了,这个方法就是判断当前获得的shareInstance是否是FactoryBean类,如果是的话返回 getObject().
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null); 复制代码
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // 如果指定name以&为前缀,此时应返回factoryBean本身的实例 if (BeanFactoryUtils.isFactoryDereference(name)) { // 实例是null直接返回null if (beanInstance instanceof NullBean) { return beanInstance; // 实例不是FactoryBean类型,直接抛出异常 } else if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass()); } else { if (mbd != null) { mbd.isFactoryBean = true; } // 返回factoryBean本身的实例 return beanInstance; } // 实例不是FactoryBean类型的,直接返回 } else if (!(beanInstance instanceof FactoryBean)) { return beanInstance; // 实例是FactoryBean类型的,且name并不存在&前缀 } else { Object object = null; if (mbd != null) { mbd.isFactoryBean = true; } else { // 直接从缓存中获取 object = this.getCachedObjectForFactoryBean(beanName); } // 此时的bean就是factoryBean,而且我们要的实例是该工厂Bean所生产的 if (object == null) { FactoryBean<?> factory = (FactoryBean)beanInstance; if (mbd == null && this.containsBeanDefinition(beanName)) { mbd = this.getMergedLocalBeanDefinition(beanName); } // 是系统定义还是用户定义的bean boolean synthetic = mbd != null && mbd.isSynthetic(); object = this.getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; } } 复制代码
上述代码主要完成了对前一步生成的bean的实例做一些解析工作
说了这么多...其实我们才说完从缓存中怎么获取单例,万一缓存中不存在呢?我们就需要去创建bean了,即从头开始bean的加载,当然,原型模式也是需要从头创建的
sharedInstance = this.getSingleton(beanName, () -> { try { return this.createBean(beanName, mbd, args); } catch (BeansException var5) { this.destroySingleton(beanName); throw var5; } }); 复制代码
这里调用的是getSingleton的一个重载方法
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized(this.singletonObjects) { // 确保缓存中还是没有该bean Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (this.logger.isDebugEnabled()) { this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } // 获得实例前记录加载状态,检测循环依赖 this.beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = this.suppressedExceptions == null; if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet(); } try { singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException var16) { singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw var16; } } catch (BeanCreationException var17) { BeanCreationException ex = var17; if (recordSuppressedExceptions) { Iterator var8 = this.suppressedExceptions.iterator(); while(var8.hasNext()) { Exception suppressedException = (Exception)var8.next(); ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } // 此时bean加载结束,移除缓存中对bean正在加载状态的记录 this.afterSingletonCreation(beanName); } if (newSingleton) { this.addSingleton(beanName, singletonObject); } } return singletonObject; } } 复制代码
其实这么一大串代码,无非就实现了try中的那两行代码,singletonObject = singletonFactory.getObject(),得到实例,最后返回。同时,返回上上段代码,我们其实可以发现,这一句话的功能其实是由 createBean 方法实现的,如下代码所示。
@FunctionalInterface public interface ObjectFactory<T> { T getObject() throws BeansException; } 复制代码
这里涉及到java8的函数式编程,不是本文重点,不再赘述
注意在得到实例的前后对一些辅助状态的操作,同时成功得到实例后会将newSingleton标记设为true,在整个代码的最后,finally阶段,如果newSingleton为true,会使用addSingleton 操作,将实例bean放入缓存,同时将singletonFactories和 earlySingletonObject 中benaName对应内容清空。
protected void beforeSingletonCreation(String beanName) { // singletonsCurrentlyInCreation 中放入beanName if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } } protected void afterSingletonCreation(String beanName) { // singletonsCurrentlyInCreation 中移除beanName if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); } } protected void addSingleton(String beanName, Object singletonObject) { synchronized(this.singletonObjects) { this.singletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } 复制代码
处理完前后的一些状态,紧接着来看下到底是怎么样创建bean的吧
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (this.logger.isTraceEnabled()) { this.logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException var9) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9); } Object beanInstance; try { // BeanPostProcessor在这里可以返回代理,实现短路 beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse); // 如果我们实现了BeanPostProcessor 扩展,这里直接返回代理实现短路效果,AOP正是基于此处 if (beanInstance != null) { return beanInstance; } } catch (Throwable var10) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10); } try { // 正常的创建bean beanInstance = this.doCreateBean(beanName, mbdToUse, args); if (this.logger.isTraceEnabled()) { this.logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) { throw var7; } catch (Throwable var8) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8); } } 复制代码
resolveBeforeInstantiation 使得在初始化前实现短路,其实就是加了BeanPostProcessor。 如果有BeanPostProcessor可以在这里实现修改bean,直接短路返回,不需要后边的正常的创建bean。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // 注意是 InstantiationAwareBeanPostProcessors if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = this.determineTargetType(beanName, mbd); if (targetType != null) { bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = bean != null; } return bean; } 复制代码
注意这个方法中的applyBeanPostProcessorsBeforeInstantiation 和 applyBeanPostProcessorsAfterInitialization,其实就是beanpostProcessor
可以看到主要是通过 InstantiationAwareBeanPostProcessors 的postprocessBeforeInstantiation 实现bean的前处理 和 BeanPostprocessor 的 postProcessAfterInitialization 实现bean的后处理
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; Object current; for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) { BeanPostProcessor processor = (BeanPostProcessor)var4.next(); current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } } return result; } public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; Object current; for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) { BeanPostProcessor processor = (BeanPostProcessor)var4.next(); current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } } return result; } 复制代码
正常的创建bean如下所示,此时没有被短路
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = this.createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } synchronized(mbd.postProcessingLock) { if (!mbd.postProcessed) { try { this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable var17) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17); } mbd.postProcessed = true; } } // 是否需要提前曝光 : 单例&允许循环依赖&当前bean正在创建中 boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName); if (earlySingletonExposure) { if (this.logger.isTraceEnabled()) { this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } // 避免循环依赖,在bean初始化完成前将ObjectFcatory放入工厂 this.addSingletonFactory(beanName, () -> { // 应用BeanPostProcessor // AOP即在这里将advice动态织入bean中,没有BeanPostProcessor的话直接返回bean return this.getEarlyBeanReference(beanName, mbd, bean); }); } Object exposedObject = bean; try { this.populateBean(beanName, mbd, instanceWrapper); exposedObject = this.initializeBean(beanName, exposedObject, mbd); } catch (Throwable var18) { if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) { throw (BeanCreationException)var18; } throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18); } if (earlySingletonExposure) { Object earlySingletonReference = this.getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) { String[] dependentBeans = this.getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length); String[] var12 = dependentBeans; int var13 = dependentBeans.length; for(int var14 = 0; var14 < var13; ++var14) { String dependentBean = var12[var14]; if (!this.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."); } } } } try { this.registerDisposableBeanIfNecessary(beanName, bean, mbd); return exposedObject; } catch (BeanDefinitionValidationException var16) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16); } } 复制代码
注意这里边的addSingletonFactory,避免循环依赖
另外跟前边一样,这里的bean最终是通过getEarlyBeanReference 得到的。
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); } } } 复制代码
有没有发现什么,singletonFactories 在这里放入(beanName,ObjectFactory),同时earlySingletonObject移除掉(beanName,Object),此时是创建中嘛,对应我们上边说的从singletonFactories中得到一个ObjectFactory
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) { Iterator var5 = this.getBeanPostProcessors().iterator(); while(var5.hasNext()) { BeanPostProcessor bp = (BeanPostProcessor)var5.next(); if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor)bp; exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); } } } return exposedObject; } 复制代码
看有没有BeanPostProcessor,做相应的处理,否则直接返回本来的bean,这里的 beanpostprocessor 是 SmartInstantiationAwareBeanPostProcessor。
到此为止,算是勉强串起来了,但是总是感觉不舒服。也罢,我们找个舒服的姿势,目光转向ApplicationContext,我们在第一节中说过了BeanFactory和ApplicationContext,还记得吧~
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); this.setConfigLocations(configLocations); if (refresh) { this.refresh(); } } 复制代码
public void refresh() throws BeansException, IllegalStateException { synchronized(this.startupShutdownMonitor) { // 准备上下文环境 this.prepareRefresh(); // 初始化BeanFactory ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); // 对BeanFactory 进行功能填充扩展 this.prepareBeanFactory(beanFactory); try { // 子类覆盖做额外处理 this.postProcessBeanFactory(beanFactory); // 激活各种BeanFactory处理器 this.invokeBeanFactoryPostProcessors(beanFactory); // 注册拦截bean创建的bean处理器,调用是在getBean的时候,注意BeanFactory必须手动注册 this.registerBeanPostProcessors(beanFactory); this.initMessageSource(); this.initApplicationEventMulticaster(); this.onRefresh(); this.registerListeners(); // 完成非延迟加载的bean的加载,提前调用getBean,进而调用beanpostProcessor this.finishBeanFactoryInitialization(beanFactory); this.finishRefresh(); } catch (BeansException var9) { if (this.logger.isWarnEnabled()) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9); } this.destroyBeans(); this.cancelRefresh(var9); throw var9; } finally { this.resetCommonCaches(); } } } 复制代码
至此,勉勉强强把我们前边说过的一些扩展组件通过bean的加载串了一遍,我也是初学者水平,难免有些理解不到之处,若有错误,多多指正~