天天看點

spring 源碼解讀十一 finishBeanFactoryInitialization(beanFactory);

今天解讀spring最重要的方法之一 finishBeanFactoryInitialization(beanFactory);

此方法用來初始化、執行個體化使用者在系統中定義的單例bean,具體有哪些bean會被初始化跟執行個體化可以在refresh 方法的第五步 invokeBeanFactoryPostProcessors(beanFactory); 這個方法執行完成後檢視BeanFactory中的BeanDefinitionMap集合中的資料,BeanDefinitionMap集合中的資料就是即将被初始化跟執行個體化的bean,當然也可能在之前的步驟中已經被初始化了,那這裡就會被忽略。。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

		// Initialize conversion service for this context.
		// 給spring的bean增加一些處理特殊資料類型的 Conversion
		// 比如說 前端頁面傳遞一個 浙江省_杭州市_下城區 服務端用省市區三個字段的 address實體類來接受

		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 BeanFactoryPostProcessor
		// (such as a PropertySourcesPlaceholderConfigurer 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.
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		// 執行個體化使用者定義的在之前環節還未被執行個體化的單例bean的接口方法
		// 實作類為 DefaultListableBeanFactory 中的 preInstantiateSingletons 方法
		beanFactory.preInstantiateSingletons();
	}
           

這裡是給要被初始化或執行個體化的bean增加一些額外的配置比如可以能要進行時間解析、字元串解析等相關處理

beanFactory.preInstantiateSingletons(); -> ConfigurableListableBeanFactory ->       
void preInstantiateSingletons() throws BeansException; ->       
DefaultListableBeanFactory -> preInstantiateSingletons() throws BeansException      
@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.
		// 擷取在之前loadBeanDefinition階段、BeanDefinitionRegistryPostProcessor、階段掃描到的所有BeanDefinitionNames集合
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		//周遊 beanNames 集合挨個建立對應的單例bean
		for (String beanName : beanNames) {
			//根據beanName 到 beanFactory 中擷取對應的BenDefinition
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//根據beanDefinition中的資訊判斷此還沒被建立的bean是是抽象、是單例、是否是懶加載
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				// 判斷此bean是否是FactoryBean的實作類
				// 如果是factoryBean的實作類
				// 則 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); 會建立此factoryBean 的實作類
				// 之後如果使用者有擷取此factoryBean建立的實際bean對象時,才會調用factoryBean 的getObject方法建立實際的bean
				/**
				 * 1、這裡容器在建立時會建立 PersonFactoryBean 這個對象并放到 singletonObjects單例一級緩存中
				 * ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("FactoryBean.xml");
				 *
				 * 	2、這裡使用者在擷取 personFactoryBean 這個對象時會調用 PersonFactoryBean 的getObject對象建立 Person對象
				 * 	并将person對象放到factoryBeanObjectCache中
				 * 	Person person = applicationContext.getBean("personFactoryBean", Person.class);
				 * */
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						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) {
							//調用 AbstractBeanFactory 中的 getBean建立 bean
							getBean(beanName);
						}
					}
				}
				else {
					//調用 AbstractBeanFactory 中的 getBean建立 bean
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}
           

之後經過一系列的調用 getBean -> doGetBean -> createBean -> doCreateBean

首先是doGetBean

protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
		//這裡可能需要處理下bean的名字比如此bean實作了FactoryBean接口那麼他的名字就會加上 & 這個符号
		//如果此bean指定了别名那就傳回此bean的别名
		String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		// 在建立bean之前先從三級緩存 (DefaultSingletonRegistry) 中擷取一下,看看是否在之前的某個環節已經提前建立好了這個bean
		// 此處的環節大概在BeanFactoryPostProcessor的實作類 或 BeanDefinitionRegistryPostProcessor的實作類中
		Object sharedInstance = getSingleton(beanName);
		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 = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					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);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				// 這裡會判斷目前bean是否有需要依賴的bean
				// 如果有則先建立依賴的bean
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						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);
						}
					}
				}

				// Create bean instance.
				// 是否是單例bean
				if (mbd.isSingleton()) {
					//建立單例bean
					sharedInstance = getSingleton(beanName, () -> {
						try {
							// 調用 AbstractAutoWireCapableBeanFactory createBean 建立bean
							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是FactoryBean的實作類則調用FactoryBean的getObject方法擷取具體的bean
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				//是否是原型bean
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					if (!StringUtils.hasLength(scopeName)) {
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
					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 {
								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;
			}
		}

		// Check if required type matches the type of the actual bean instance.
		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;
	}
           

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.
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			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.
			// 這裡看上面的翻譯是說給 BeanPostProcessors 一個機會來傳回一個代理對象對于目标對象
			// 其實這裡面做了很多事情,并且容易讓人誤解
			// 首先這裡傳回的不是spring 的代理對象而是由使用者實作的某個類的對象可以是new出來的,也可以是經過代理實作的
			// 其次如果系統有aop的相關配置,這裡會執行個體化aop的相關配置類,但是不會傳回具體對象的代理對象
			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(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		//先準備一個執行個體bean的包裝類,然後在下面的步驟中執行個體化一個bean并設定到包裝類中
		//
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}

		//這裡首先執行個體化一個bean,執行個體化的方法有很多種

		/**
		 * 1、Supplier 的方式 - 屬于使用者自定義方式
		 * 2、factoryMethod 的方式 - 屬于使用者自定義方式(其中在@Configucationz注解、 @Component注解 類中定義的 @bean注解類就是走的這種方式)
		 * 3、在某個注解類中通過在構造函數上加 @Autowire 注解的方式注入其他bean 這種用法較少
		 * 4、通過反射調用類的構造方法進行執行個體化 - 如果使用者沒有進行上面三種方式的設定,那預設就會用第四種反射調用構造方法進行執行個體化
		 *    這裡的反射調用類的構造方法也有兩種分類、一種是普通類調用構造方法執行個體化,一種是代理類調用構造方法執行個體化
		 *    普通類調用構造方法執行個體化後,就完成了。但是代理類最終傳回的是代理對象,但這裡有兩種方式
		 *
		 *    一種方式是在生成類的Class時就直接生成代理類的Class比如使用@Configuration 注解的類在前面 BeanFactoryPostProcessor
		 *    的實作類@ConfigurationClassPostProcessor 的beanFactoryPostProcessor 方法執行時直接傳回的就是代理類的Class,
		 *    然後調用代理類的構造方法生成代理對象
		 *
		 *    另一種方式是先生成普通對象然後在BeanPostProcessor 的實作類 AspectJAwareAdvisorAutoProxyCreator(當在配置檔案中配置了aop tx事務、等等
		 *    需要生成代理對象時, spring 架構會幫我們自動注入 AspectJAwareAdvisorAutoProxyCreator 這個類,具體怎麼注入的 可以看下 AopNamespaceHandler
		 *    這個類裡面的AspectJAutoProxyBeanDefinitionParser 這個類, 具體的加載關系在之前的章節已經聊過了就不說了) 的 getEarlyBeanReference 方法中
		 *    判斷目前類是否要進行代理生成,如果要被代理生成則調用 jdk的 proxy或者 cglib的 Enhancer 進行代理類的生成,并替換之前生成的普通類
		 *    這裡有可能有同學在 AspectJAwareAdvisorAutoProxyCreator 裡面找不到 getEarlyBeanReference 這個方法, 在 AbstractAutoProxyCreator裡面
		 * */

		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}

		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}


		/**
		 * 這裡會對注解的bean中的相關屬性注解(@AutoWire、@value、@Resource、@PostConstruct、@PreDestroy)進行解析(隻是解析,并不會實際注入)
		 * 實際的屬性注入要到 InstantiationAwareBeanPostProcessor、MergedBeanDefinitionPostProcessor
		 * DestructionAwareBeanPostProcessor 等 BeanPostProcessor 的子接口的 相關方法被調用時才會被注入
		 *
		 * @AutoWire、@value 會被 CommonAnnotationBeanPostProcessor 的 postProcessMergedBeanDefinition 這個方法解析到
		 * @Resource 會被 CommonAnnotationBeanPostProcessor 的 postProcessMergedBeanDefinition 這個方法解析到
		 * @PostConstruct、@PreDestroy 會被 InitDestroyAnnotationBeanPostProcessor 的 postProcessMergedBeanDefinition 這個方法解析到
		 *
		 * */
		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;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.

		/**
		 * 這裡是處理循環引用的關鍵,spring會将隻經過執行個體化但是未經過初始化的對象統一都放入三級緩存的第三級緩存中
		 * DefaultSingletonBeanRegistry -> Map<String, ObjectFactory<?>> singletonFactories
		 * 可以看到 singletonFactories是一個map結構,裡面的key是 bean的名稱 value是 ObjectFactory
		 * 實際注入的 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		 * key是bean的名稱value是 lambda表達式 () -> getEarlyBeanReference(beanName, mbd, bean)
		 * 後面在它被依賴引用的時候可以根據是否需要注入代理對象決定是傳回原始對象還是調用 getEarlyBeanReference 傳回代理對象
		 * */
		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");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {

			/**
			 * 給剛剛執行個體化之後的對象的屬性進行初始化
			 * 這裡的初始化主要是給對象屬性指派
			 * 包括基本屬性、引用屬性等,實際上很複雜包括基本資料類型的指派,集合類型的指派、配置檔案類型的屬性指派
			 * */
			populateBean(beanName, mbd, instanceWrapper);

			/**
			 * 給剛剛執行個體化并給屬性指派之後的對象在進行一些初始化
			 * 這裡的初始化主要是指調用相關的初始化方法
			 * 包括對 Aware 的實作類 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware這三個接口的方法調用
			 * 包括對 InitDestroyAnnotationBeanPostProcessor @PostConstruct 注解的方法的調用
			 * 包括對 InitializingBean 的 afterPropertiesSet 方法的調用
			 * 包括對BeanPostProcessor的 相關子接口的 postProcessBeforeInitialization、postProcessAfterInitialization 的方法的調用
			 * */
			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 " +
								"'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;
	}
           

 這裡隻是理出了大概的主線實際上這裡的 createBeanInstance、

applyMergedBeanDefinitionPostProcessors、      
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));      
populateBean、initializeBean、registerDisposableBeanIfNecessary 等方法中都是有更深層次的業務邏輯處理流程需要慢慢去整理的