天天看點

SpringBoot finishBeanFactoryInitialization(beanFactory) 方法分析(bean執行個體化)

finishBeanFactoryInitialization(beanFactory)
/**
	 * Finish the initialization of this context's bean factory,
	 * initializing all remaining singleton beans.
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		// 判斷beanFactory是否有CONVERSION_SERVICE_BEAN_NAME的實作,如果有的話設定屬性。為上下文初始化類型轉換器。
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		// 檢查上下文中是否存在類型轉換器
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		//标記正在執行個體化當中,禁止對 bean 的定義再修改。
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		// 進行單例bean的執行個體化
		beanFactory.preInstantiateSingletons();
	}
           
  1. beanFactory.freezeConfiguration();标志正在執行個體化當中,同時,記錄正在執行個體化的beanDefinition的名字。
  2. beanFactory.preInstantiateSingletons();執行個體化單例bean。
SpringBoot finishBeanFactoryInitialization(beanFactory) 方法分析(bean執行個體化)

進入preInstantiateSingletons()方法

@Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		//周遊一個副本以允許init方法,而init方法反過來注冊新的bean定義。
		//盛放所有的beanName,所有的需要執行個體化的beanName都在這裡,包括Spring斷斷續續添加的, Aspectj的, 程式員通過注解辨別的
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			//合并父類BeanDefinition
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//三個條件,抽象,單例,非懶加載,符合條件再進行加載
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//檢驗是否是 FactoryBean 類型的對象,如果是則加上&再調用getBean(beanName),如果不是則直接調用。
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
											((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}
           
  1. 擷取所有的beanNames,然後周遊判斷是否符合執行個體化的條件。
  2. 合并父 beanDefinition 與子 beanDefinition,判斷這個bean是否是 非抽象、非懶加載的單例bean,是的話進入執行個體化。
  3. 執行個體化首先判斷是否為FactoryBean,FactoryBean 适用于 Bean 的建立過程比較複雜的場景。FactoryBean 的話,在 beanName 前面加上 ‘&’ 符号。再調用 getBean()。對FactoryBean而言,這個Bean不是簡單的Bean,而是一個能生産或者修飾對象生成的工廠Bean,它的實作與設計模式中的工廠模式和修飾器模式類似 。
  4. 調用getBean();

進入getBean(beanName)方法

@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
           

進入doGetBean方法

/**
	 * Return an instance, which may be shared or independent, of the specified bean.
	 * @param name the name of the bean to retrieve
	 * @param requiredType the required type of the bean to retrieve
	 * @param args arguments to use when creating a bean instance using explicit arguments
	 * (only applied when creating a new instance as opposed to retrieving an existing one)
	 * @param typeCheckOnly whether the instance is obtained for a type check,
	 * not for actual use
	 * @return an instance of the bean
	 * @throws BeansException if the bean could not be created
	 */

           

getBean 方法是我們經常用來擷取 bean 的,但它也同時封裝了初始化的過程,已經初始化過了就從容器中直接傳回,否則就先初始化再傳回

@Override
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

// getBean 方法是我們經常用來擷取 bean 的,但它也同時封裝了初始化的過程,已經初始化過了就從容器中直接傳回,否則就先初始化再傳回
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
                          @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

    // 擷取一個 “正統的” beanName,處理兩種情況,一個是前面說的 FactoryBean(前面帶 ‘&’),
    // 一個是别名問題,因為這個方法是 getBean,擷取 Bean 用的,你要是傳一個别名進來,是完全可以的
    final String beanName = transformedBeanName(name);
    // 這個是傳回值
    Object bean;

    // 檢查下是不是已經建立過了
    Object sharedInstance = getSingleton(beanName);
     // if 内部是擷取 bean 的邏輯。
     // 這裡說下 args,前面我們一路進來的時候都是 getBean(beanName),是以 args 傳參其實是 null 的,
     // 但是如果 args 不為空的時候,那麼意味着調用方不是希望擷取 Bean,而是建立 Bean 
    if (sharedInstance != null && args == null) {
        if (logger.isTraceEnabled()) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                        "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
                logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        // 下面這個方法,如果是普通 Bean 的話,直接傳回 sharedInstance,如果是 FactoryBean 的話,傳回它建立的那個執行個體對象。
        // 如果對 FactoryBean 不熟悉,附錄中有介紹。
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } 
    // else 内部是初始化 bean 的邏輯
    else {
        // 目前 beanName 的 prototype 類型的 bean 正在被建立則抛異常
        // 往往是因為陷入了循環引用。prototype 類型的 bean 的循環引用是沒法被解決的。這跟 Java 裡面的一樣,會導緻棧溢出。
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        BeanFactory parentBeanFactory = getParentBeanFactory();
        // 檢查一下這個 BeanDefinition 在容器中是否存在
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // 如果目前容器不存在這個 BeanDefinition,試試父容器中有沒有
            String nameToLookup = originalBeanName(name);
            // 傳回父容器的查詢結果 
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                // Delegation to parent with explicit args.
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                        nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else if (requiredType != null) {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
            else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }
        // typeCheckOnly 為 false,将目前 beanName 放入一個 alreadyCreated 的 Set 集合中
        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }
       /**
        * 稍稍總結一下:
        * 到這裡的話,要準備建立 Bean 了,對于 singleton 的 Bean 來說,容器中還沒建立過此 Bean;
        * 對于 prototype 的 Bean 來說,本來就是要建立一個新的 Bean。
        */
        try {
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // 先初始化依賴的所有 Bean,注意,這裡的依賴指的是 depends-on 中定義的依賴
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    // 檢查是不是有循環依賴
                    // 這裡的依賴還是 depends-on 中定義的依賴
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    // 注冊一下依賴關系
                    registerDependentBean(dep, beanName);
                    try {
                        // 先初始化被依賴項
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // 如果是 singleton scope 的,建立 singleton 的執行個體
            if (mbd.isSingleton()) {
                 // 這裡并沒有直接調用 createBean 方法建立 bean 執行個體,而是通過 getSingleton(String, ObjectFactory) 方法擷取 bean 執行個體。  
                 // getSingleton(String, ObjectFactory) 方法會在内部調用 ObjectFactory 的 getObject() 方法建立 bean,并會在建立完成後,
                 // 将 bean 放入緩存中。
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        // 執行建立 Bean,詳情後面再說
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                // 跟上面的一樣,如果是普通 Bean 的話,直接傳回 sharedInstance,如果是 FactoryBean 的話,傳回它建立的那個執行個體對象。
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

            // 如果是 prototype scope 的,建立 prototype 的執行個體
            else if (mbd.isPrototype()) {
                // prototype 對象每次擷取都會建立新的執行個體
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    // 執行建立 Bean
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }

            // 如果不是 singleton 和 prototype 的話,需要委托給相應的實作類來處理
            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, () -> {
                        beforePrototypeCreation(beanName);
                        try {
                            // 執行建立 Bean
                            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;
        }
    }

    // 最後,檢查一下類型對不對,不對的話就抛異常,對的話就傳回了
    if (requiredType != null && !requiredType.isInstance(bean)) {
        try {
            T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
            return convertedBean;
        }
        catch (TypeMismatchException ex) {
            if (logger.isTraceEnabled()) {
                logger.trace("Failed to convert bean '" + name + "' to required type '" +
                        ClassUtils.getQualifiedName(requiredType) + "'", ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}
           
  1. 擷取一個 “正統的” beanName,處理兩種情況,一個是前面說的 FactoryBean(前面帶 ‘&’),一個是别名問題,因為這個方法是 getBean,擷取 Bean 用的,你要是傳一個别名進來,是完全可以的。
  2. getSingleton(beanName),跟進源碼檢視這個方法,重點分析下面這行代碼,這個singletonObjects就是微觀層面的IOC容器,因為我們的getBean()方法存在遞歸調用,通過getSingleton()保證不會重複建立已經存在的執行個體。
  1. 下面這段代碼完成真正的bean的建立
if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						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;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
           

分析createBean()方法

@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		// 做各種各樣的屬性值的指派, 比如這種 通過Spring的Bean傳遞給Spring架構的值  ==> bd.setPropertyValue("aaa")
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			// 處理 lookup-method 和 replace-method 配置,Spring 将這兩個配置統稱為 override method
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			// 在執行個體化之前完成一次解析操作,這個方法主要是執行個體化實作了InstantiationAwareBeanPostProcessor的bean的postProcessBeforeInstantiation方法傳回的執行個體。
			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);
		}

		try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}
           

進入doCreateBean方法

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
        throws BeanCreationException { 
     
    // BeanWrapper 是一個基礎接口,由接口名可看出這個接口的實作類用于包裹 bean 執行個體。
    // 通過 BeanWrapper 的實作類可以友善的設定/擷取 bean 執行個體的屬性
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        // 從緩存中擷取 BeanWrapper,并清理相關記錄
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        // 建立 bean 執行個體,并将執行個體包裹在 BeanWrapper 實作類對象中傳回,之後會細談
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 此處的 bean 可以認為是一個原始的 bean 執行個體,暫未填充屬性
    final Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // 涉及接口:MergedBeanDefinitionPostProcessor,用于處理已“合并的 BeanDefinition”,這塊細節就不展開了
    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;
        }
    }

    // earlySingletonExposure 是一個重要的變量,用于解決循環依賴,該變量表示是否提前暴露,
    // earlySingletonExposure = 單例 && 是否允許循環依賴 && 是否存于建立狀态中
    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");
        }
        // 添加工廠對象到 singletonFactories 緩存中
        addSingletonFactory(beanName, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
                // 擷取早期 bean 的引用,如果 bean 中的方法被 AOP 切點所比對到,此時 AOP 相關邏輯會介入
                return getEarlyBeanReference(beanName, mbd, bean);
            }
        });
    }

    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) {
        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<>(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.");
                }
            }
        }
    }

    // 注冊銷毀邏輯
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}
           
  1. 從緩存中擷取 BeanWrapper 實作類對象,并清理相關記錄,BeanWrapper 用到了裝飾器模式
  2. 若未命中緩存,則建立 bean 執行個體,并将執行個體包裹在 BeanWrapper 實作類對象中傳回
  3. 應用 MergedBeanDefinitionPostProcessor 後置處理器相關邏輯
  4. 根據條件決定是否提前暴露 bean 的早期引用(early reference),用于處理循環依賴問題
  5. 調用 populateBean 方法向 bean 執行個體中填充屬性
  6. 調用 initializeBean 方法完成餘下的初始化工作
  7. 注冊銷毀邏輯

    接下來我們挑 doCreateBean 中的三個細節出來說說。一個是建立 Bean 執行個體的 createBeanInstance 方法,一個是依賴注入的 populateBean 方法,還有就是回調方法 initializeBean。

1. 建立執行個體

/**
	 * Create a new instance for the specified bean, using an appropriate instantiation strategy:
	 * factory method, constructor autowiring, or simple instantiation.
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @param args explicit arguments to use for constructor or factory method invocation
	 * @return a BeanWrapper for the new instance
	 * @see #obtainFromSupplier
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 * @see #instantiateBean
	 */
	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		Class<?> beanClass = resolveBeanClass(mbd, beanName);
		// 檢測這個類的通路權限, Spring預設是 允許通路非public類型的方法
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}

		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}
		// 如果工廠方法不為空,則通過工廠方法建構 bean 對象。
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// 如果不是第一次建立,比如第二次建立 prototype bean。這種情況下,我們可以從第一次建立知道,
    	// 采用無參構造函數,還是構造函數依賴注入來完成執行個體化。
    	// 這裡的 resolved 和 mbd.constructorArgumentsResolved 将會在 bean 第一次執行個體化的過程中被設定.
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				// 通過有參構造器構造 bean 對象
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				// 通過無參構造器構造 bean 對象
				return instantiateBean(beanName, mbd);
			}
		}

		// Candidate constructors for autowiring?
		// 判斷是否采用有參構造函數
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			// 通過有參構造器構造 bean 對象
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// Preferred constructors for default construction?
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// No special handling: simply use no-arg constructor.
		// 通過無參構造器構造 bean 對象
		return instantiateBean(beanName, mbd);
	}
           
  1. 檢測類的通路權限,若禁止通路,則抛出異常
  2. 若工廠方法不為空,則通過工廠方法建構 bean 對象,并傳回結果
  3. 若構造方式已解析過,則走快捷路徑建構 bean 對象,并傳回結果
  4. 如第三步不滿足,則通過組合條件決定使用哪種方式建構 bean 對象

2.屬性注入

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
   // bean 執行個體的所有屬性都在這裡了
   PropertyValues pvs = mbd.getPropertyValues();

   if (bw == null) {
      if (!pvs.isEmpty()) {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      else {
         return;
      }
   }

   // 到這步的時候,bean 執行個體化完成(通過工廠方法或構造方法),但是還沒開始屬性設值,
   // InstantiationAwareBeanPostProcessor 的實作類可以在這裡對 bean 進行狀态設定,比如忽略屬性值的設定
   boolean continueWithPropertyPopulation = true;
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            // 如果傳回 false,代表不需要進行後續的屬性設值,也不需要再經過其他的 BeanPostProcessor 的處理
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
               continueWithPropertyPopulation = false;
               break;
            }
         }
      }
   }

   if (!continueWithPropertyPopulation) {
      return;
   }

   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
         mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

      // 通過名字找到所有屬性值,如果是 bean 依賴,先初始化依賴的 bean。記錄依賴關系
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
         autowireByName(beanName, mbd, bw, newPvs);
      }

      // 通過類型裝配。複雜一些
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
         autowireByType(beanName, mbd, bw, newPvs);
      }

      pvs = newPvs;
   }

   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

   if (hasInstAwareBpps || needsDepCheck) {
      PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      if (hasInstAwareBpps) {
         for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
               // 這裡有個非常有用的 BeanPostProcessor 進到這裡: AutowiredAnnotationBeanPostProcessor
               // 對采用 @Autowired、@Value 注解的依賴進行設值
               pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvs == null) {
                  return;
               }
            }
         }
      }
      if (needsDepCheck) {
         checkDependencies(beanName, mbd, filteredPds, pvs);
      }
   }
   // 設定 bean 執行個體的屬性值
   applyPropertyValues(beanName, mbd, bw, pvs);
}
           
  1. 擷取屬性清單 pvs
  2. 在屬性未注入之前,使用後置處理器進行狀态設定
  3. 根據名稱或類型解析相關依賴
  4. 再次應用後置處理,用于實作基于注解的屬性注入
  5. 将屬性應用到 bean 對象中

    第3步,也就是根據名稱或類型解析相關依賴。該邏輯隻會解析依賴,并不會将解析出的依賴立即注入到 bean 對象中。這裡解析出的屬性值是在 applyPropertyValues 方法中統一被注入到 bean 對象中的。我們常用到的注解式屬性注入比較多,是以這裡就看一下基于注解的屬性注入。

    2.1基于注解的屬性注入

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    // 找到要以注解形式注入的屬性資訊
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
    try {
        // 開始注入
        metadata.inject(bean, beanName, pvs);
    }
    catch (BeanCreationException ex) {
        throw ex;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
    }
    return pvs;
}

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    Collection<InjectedElement> checkedElements = this.checkedElements;
    Collection<InjectedElement> elementsToIterate =
            (checkedElements != null ? checkedElements : this.injectedElements);
    if (!elementsToIterate.isEmpty()) {
        for (InjectedElement element : elementsToIterate) {
            if (logger.isTraceEnabled()) {
                logger.trace("Processing injected element of bean '" + beanName + "': " + element);
            }
            // 對每個屬性依次注入
            element.inject(target, beanName, pvs);
        }
    }
}

@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    // 要注入的字段
    Field field = (Field) this.member;
    Object value;
    // 會把注入過的屬性緩存起來
    if (this.cached) {
        value = resolvedCachedArgument(beanName, this.cachedFieldValue);
    }
    else {
         // 字段的描述,包括字段名、是否必需、所屬類、注解資訊等
        DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
        desc.setContainingClass(bean.getClass());
        Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
        Assert.state(beanFactory != null, "No BeanFactory available");
        // 類型轉換器,用于将 String 類型轉換成其它類型
        TypeConverter typeConverter = beanFactory.getTypeConverter();
        try {
            // 核心,實際解析屬性的地方,傳回的是依賴的執行個體
            value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
        }
        catch (BeansException ex) {
            throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
        }
        synchronized (this) {
            if (!this.cached) {
                if (value != null || this.required) {
                    this.cachedFieldValue = desc;
                    registerDependentBeans(beanName, autowiredBeanNames);
                    if (autowiredBeanNames.size() == 1) {
                        String autowiredBeanName = autowiredBeanNames.iterator().next();
                        if (beanFactory.containsBean(autowiredBeanName) &&
                                beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                            this.cachedFieldValue = new ShortcutDependencyDescriptor(
                                    desc, autowiredBeanName, field.getType());
                        }
                    }
                }
                else {
                    this.cachedFieldValue = null;
                }
                this.cached = true;
            }
        }
    }
    if (value != null) {
        ReflectionUtils.makeAccessible(field);
        // 通過反射注入
        field.set(bean, value);
    }
}

public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
        Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {

    descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
    if (javaUtilOptionalClass == descriptor.getDependencyType()) {
        return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName);
    }
    else if (ObjectFactory.class == descriptor.getDependencyType() ||
            ObjectProvider.class == descriptor.getDependencyType()) {
        return new DependencyObjectProvider(descriptor, requestingBeanName);
    }
    else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
        return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
    }
    else {
        Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
                descriptor, requestingBeanName);
        if (result == null) {
            // 核心,解析依賴
            result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
        }
        return result;
    }
}

public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
        Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {

    InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
    try {
        // 該方法最終調用了 beanFactory.getBean(String, Class),從容器中擷取依賴
        Object shortcut = descriptor.resolveShortcut(this);
        // 如果容器中存在所需依賴,這裡進行斷路操作,提前結束依賴解析邏輯
        if (shortcut != null) {
            return shortcut;
        }

        Class<?> type = descriptor.getDependencyType();
        // 處理 @value 注解
        Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
        if (value != null) {
            if (value instanceof String) {
                String strVal = resolveEmbeddedValue((String) value);
                BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
                value = evaluateBeanDefinitionString(strVal, bd);
            }
            TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
            return (descriptor.getField() != null ?
                    converter.convertIfNecessary(value, type, descriptor.getField()) :
                    converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
        }

        // 解析數組、list、map 等類型的依賴
        Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
        if (multipleBeans != null) {
            return multipleBeans;
        }

        /*
         * findAutowireCandidates 這個方法邏輯比較複雜,它傳回的是一個<名稱,類型/執行個體>的候選清單。比如下面的配置:
         *
         *   <bean name="mongoDao" class="com.huzb.demo.MongoDao" primary="true"/>
         *   <bean name="service" class="com.huzb.demo.Service" autowire="byType"/>
         *   <bean name="mysqlDao" class="com.huzb.demo.MySqlDao"/>
         *
         * 我們假設這個屬性的類型是 Dao,而 mongoDao 和 mysqlDao 都繼承了 Dao 接口,mongoDao 已被執行個體化,mysqlDao
         * 尚未執行個體化,那麼傳回的候選清單就是:
         *
         *   matchingBeans = [ <"mongoDao", [email protected]>, <"mysqlDao", [email protected]> ]
         * 
         * 方法内部的工作流程如下:
         *   1. 方法開始時有一個 type 記錄需要的屬性的類型資訊。
         *   2. 類型如果是容器對象(我們在容器準備時放進 resolvableDependencies 的),那直接從容器中拿到,加入候選清單。
         *   3. 根據類型資訊從 BeanFactory 中擷取某種類型 bean 的名稱清單,比如按上面配置拿到的就是["mongoDao","mysqlDao"]
         *   4. 周遊上一步得到的名稱清單,并判斷 bean 名稱對應的 bean 是否是合适的候選項,若是合适,則把執行個體對象(已執行個體化)
         *       或類型(未執行個體化)加入候選清單
         *   5. 傳回候選清單
         */
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
        if (matchingBeans.isEmpty()) {
            if (isRequired(descriptor)) {
                // 抛出 NoSuchBeanDefinitionException 異常
                raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
            }
            return null;
        }

        String autowiredBeanName;
        Object instanceCandidate;

        if (matchingBeans.size() > 1) {
            /*
             * matchingBeans.size() > 1,則表明存在多個可注入的候選項,這裡判斷使用哪一個候選項。
             * 候選項的判定規則是:
             * 1)聲明了 primary 的優先級最高
             * 2)實作了排序接口,如 Ordered 的優先級比沒實作排序接口的高;同樣實作了排序接口的會通過比較器比較
             * 3)還沒有得到結果的話,則按字段名進行比對
             */
            autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
            if (autowiredBeanName == null) {
                if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
                    // 抛出 NoUniqueBeanDefinitionException 異常
                    return descriptor.resolveNotUnique(type, matchingBeans);
                }
                else {
                    return null;
                }
            }
            // 根據解析出的 autowiredBeanName,擷取相應的候選項
            instanceCandidate = matchingBeans.get(autowiredBeanName);
        }
        else { // 隻有一個候選項,直接取出來即可
            Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
            autowiredBeanName = entry.getKey();
            instanceCandidate = entry.getValue();
        }

        if (autowiredBeanNames != null) {
            autowiredBeanNames.add(autowiredBeanName);
        }

        // 傳回候選項執行個體,如果執行個體是 Class 類型,則調用 beanFactory.getBean(String, Class) 擷取相應的 bean。否則直接傳回即可
        return (instanceCandidate instanceof Class ?
                descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
    }
    finally {
        ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
    }
}
           
  1. 找到要以注解形式注入的屬性資訊
  2. 依次對每個字段操作
  3. 構造字段的描述,包括字段名、是否必需、所屬類、注解資訊等
  4. 擷取屬性值
    1. @Value 設定的值,将 String 轉成對應類型後傳回
    2. 依賴的類型是個數組或集合,會将符合條件的 bean 全部放在數組或集合中傳回
    3. 普通類型傳回一個候選清單,然後根據判定規則選出優先級最高的一個
  5. 如果得到的屬性是個 Class 對象,則調用 getBean 生成執行個體
  6. 通過反射注入

3、處理各種回調

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged(new PrivilegedAction<Object>() {
         @Override
         public Object run() {
            invokeAwareMethods(beanName, bean);
            return null;
         }
      }, getAccessControlContext());
   }
   else {
      // 如果 bean 實作了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回調
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      // BeanPostProcessor 的 postProcessBeforeInitialization 回調
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      // 處理 bean 中定義的 init-method,
      // 或者如果 bean 實作了 InitializingBean 接口,調用 afterPropertiesSet() 方法
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }

   if (mbd == null || !mbd.isSynthetic()) {
      // BeanPostProcessor 的 postProcessAfterInitialization 回調
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
}
           

參考資料:

1https://huzb.me/2019/03/04/Spring%E6%BA%90%E7%A0%81%E6%B5%85%E6%9E%90%E2%80%94%E2%80%94bean%20%E5%88%9B%E5%BB%BA%E6%B5%81%E7%A8%8B/#4%E3%80%81getSingleton

2.https://coding.imooc.com/class/404.html

繼續閱讀