方法执行流程图
doCreateBean.xmind
来到方法源码
// 没有特殊情况下的创建对象try {Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.// instanceWrapper 拿着创建好的对象BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {// 第一次加载的话,缓存中没有该bean所以instanceWrapper仍然为nullinstanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {// 创建包装对象instanceWrapper = createBeanInstance(beanName, mbd, args);}// 创建包装对应的对象,此时属性全都是零值Object bean = instanceWrapper.getWrappedInstance();// 获取类对象Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {// 设置Class对象mbd.resolvedTargetType = beanType;}// Allow post-processors to modify the merged bean definition.synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {// bean的后置处理器applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);} catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.// 利用缓存处理循环依赖boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}// !!! 单例 Bean 对象已经实例化,属性还没处理,可以通过引用找到堆上的这个对象// 将这个状态下的bean放到三级缓存中。表示可以从三级缓存中拿到这个已经创建但是还没有补充完属性的对象addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// 初始化属性// Initialize the bean instance.Object exposedObject = bean;try {// 填充属性populateBean(beanName, mbd, instanceWrapper);// 初始化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) {// 从缓存中获取beanObject earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;// 判断是否有其他依赖的bean} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}// 如果依然有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 " +"'getBeanNamesForType' 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;}
创建 BeanWrapper
实例化对象,首先创建一个BeanWrapper对象,用来持有我们将要创建的对象,BeanWrapper 的父类继承关系如下:
创建对象实例
执行扩展处理器
// Allow post-processors to modify the merged bean definition.synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {// bean的后置处理器applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);} catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}
加入三级缓存
实例化对象后,目前该 bean 的状态:
- 单例 bean 对象已经实例化,属性还没处理
- 将这个状态下的bean放到三级缓存singletonFactories中
该bean可以从三级缓存中拿到,通过引用可以找到堆上的这个对象
// 是否需要提前曝光条件:1.单例 2.允许循环以来 3.bean正在创建中boolean earlySingletonExposure = (mbd.isSingleton()&& this.allowCircularReferences&& isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName + "'to allow for resolving potential circular references");}/*为避免后期循环依赖,可以在bean初始化完成前将创建实例的 ObjectFactory 加入工厂缓存到这里↓1.单例bean对象已经实例化,属性还没处理2.将这个状态下的bean放到三级缓存singletonFactories中3.该bean可以从三级缓存中拿到,通过引用可以找到堆上的这个对象// 其中我们熟知的AoP就是在这里将 advice 动态织入bean中,若没有则直接返回 bean,不做任何处理*/addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}
进入方法 addSingletonFactory。该方法的第二个参数是一个接口:
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);}}}
该方法的第二个参数是一个函数式接口:
@FunctionalInterfacepublic interface ObjectFactory<T> {T getObject() throws BeansException;}
AbstractAutowireCapableBeanFactory 中匿名内部类的形式用 getEarlyBeanReference 实现了该接口。
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {Object exposedObject = bean;if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);}}}return exposedObject;}
填充属性
初始化对象
检测循环依赖
if (earlySingletonExposure) {// 从缓存中获取beanObject earlySingletonReference = getSingleton(beanName, false);// 检测到循环依赖的情况下不为空if (earlySingletonReference != null) {// 如果exposedObject 没有在初始化方法中被改变,说明没有被增强if (exposedObject == bean) {exposedObject = earlySingletonReference;} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for (String dependentBean : dependentBeans) {// 检测依赖if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}// actualDependentBeans不为空异常/*因为bean创建好了,那么它依赖的bean应该都已经创建好了。如果actualDependentBeans不为空表示依赖的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 " +"'getBeanNamesForType' 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);}
