15-Spring源碼解析之refresh(8)——【finishBeanFactoryInitialization】

Spring版本:<version>5.2.1.RELEASE</version>

上一篇:14-Spring源碼解析之refresh(7)——【onRefresh】和【registerListeners】

上一篇,我們講解了refresh方法中調用的第9個onRefresh方法和第10個registerListeners方法。接着本篇文章講解refresh方法調用的第11個finishBeanFactoryInitialization方法。也是Spring中最核心的方法。

一、finishBeanFactoryInitialization

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		// 初始化上下文的轉換服務
		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.
		// 註冊默認的嵌入值解析器 
		// 如:PropertyPlaceholderConfigurer 
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// 根據LoadTimeWeaverAware類型,來獲取LoadTimeWeaverAwareName,如果有則創建這個LoadTimeWeaverAware
		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.
		// 凍結所有的beanDefinition, 實際上就是將ArrayList類型的beanDefinition轉爲String類型
		beanFactory.freezeConfiguration();

//-------------------------------------加載Bean---------------------------------------------
		// Instantiate all remaining (non-lazy-init) singletons.
		// 把所有非懶加載的Bean都實例化
		beanFactory.preInstantiateSingletons();
	}

	public void freezeConfiguration() {
		this.configurationFrozen = true;
		this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
	}

二、preInstantiateSingletons方法

	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方法註冊新的beanDefinition。
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			// 是獲取緩存的BeanDefinition對象併合並其父類和本身的屬性
			// BeanDfinitiaon定義公共的抽象累是AbstractBeanDefinition。
			// 普通的Bean在Spring註冊BeanDefinition的時候,實例化出來的是GenericBeanDefinition
			// Spring內置的Bean在註冊BeanDefinition的時候,實例化出來的是RootBeanDefinition,
			// 這時候,就要用getMergedLocalBeanDefinition將所有的BeanDefinition都轉換爲RootBeanDefinition
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

			// 不是抽象類&是單例&非懶加載
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				// 判斷是否是工廠Bean
				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 {
//-------------------------------------核心方法--------------------------------------------
					// 普通Bean的實例化、屬性注入、初始化等
					// 下一篇文章介紹
					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();
				}
			}
		}
	}

三、總結

refresh方法調用的第11個方法finishBeanFactoryInitialization所實現的功能:

  • 【功能一】

    • 將所有BeanDefintiion的都轉換爲 RootBeanDefinition類型,並判斷是否是工廠Bean,若是則按照工廠Bean處理
  • 【功能二】

    • 根據beanName創建所有非工廠Bean , 即調用getBean方法

下一篇文章,我們就來好好分析一下getBean方法是如何加載Bean的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章