Spring源碼(三)SpringIOC初始化過程-完成Bean的初始化

SpringIOC初始化過程-完成Bean的初始化(finishBeanFactoryInitialization)

上一篇中已經講解完**invokeBeanFactoryPostProcessors(beanFactory);**方法;咱們看看下面還有什麼方法java

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		//準備工做包括設置啓動時間,是否激活標識位,
		// 初始化屬性源(property source)配置
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		//返回一個factory 爲何須要返回一個工廠
		//由於要對工廠進行初始化 
           /** 這裏說明一下:若是你使用是的xml配置的方式就會執行 AbstractRefreshableApplicationContext的refreshBeanFactory方法去加載xml配置信息;由於ClassPathXmlApplicationContext是它的子類;如今咱們使用的是註解配置的方式因此會執行GenericApplicationContext的refreshBeanFactory方法,這個方法就是隻返回了一個beanFactory**/
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		//準備工廠
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.

			//這個方法在當前版本的spring是沒用任何代碼的
			//可能spring期待在後面的版本中去擴展吧
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			//在spring的環境中去執行已經被註冊的 factory processors
			//設置執行自定義的ProcessBeanFactory 和spring內部本身定義的
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			//註冊beanPostProcessor
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			// 初始化當前 ApplicationContext 的 MessageSource,國際化這裏就不展開說了
			initMessageSource();

			// Initialize event multicaster for this context.
			//初始化應用事件廣播器
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			// 從方法名就能夠知道,典型的模板方法(鉤子方法),
			// 具體的子類能夠在這裏初始化一些特殊的 Bean(在初始化 singleton beans 以前)
			onRefresh();

			// Check for listener beans and register them.
			// 註冊事件監聽器,監聽器須要實現 ApplicationListener 接口。這也不是咱們的重點,過
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			// 重點,重點,重點
			// 初始化全部的 singleton beans
			//(lazy-init 的除外)
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			// 最後,廣播事件,ApplicationContext 初始化完成
			finishRefresh();
		}
           //.......
複製代碼

國際化初始化應用事件廣播器,註冊事件監聽在這裏就不過多的闡述了,要否則真的是沒完沒了了;咱們重點看下初始化全部的 singleton beans方法;git

初始化全部的 singleton beans -finishBeanFactoryInitialization(beanFactory);

**finishBeanFactoryInitialization(beanFactory);**方法除了懶加載以外的beans,在這裏都會進行初始化;github

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 首先,初始化名字爲 conversionService 的 Bean。這裏不是重點
		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);

		// 這裏將beanDefinitionNames賦值給frozenBeanDefinitionNames
		//目的就是到了這一步,Spring 已經開始預初始化 singleton beans 了,
		// 不能再出現其餘的 bean 定義解析、加載、註冊了;
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		//實例化全部的單例對象
		beanFactory.preInstantiateSingletons();
	}
複製代碼

重點是preInstantiateSingletons();方法:spring

public void preInstantiateSingletons() throws BeansException {
		if (logger.isDebugEnabled()) {
			logger.debug("Pre-instantiating singletons in " + this);
		}
		//全部bean的名字
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		// 觸發全部非延遲加載單例beans的初始化,主要步驟爲調用getBean
		for (String beanName : beanNames) {
			//合併父BeanDefinition
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//是否爲抽象類,是不是單例,是不是懶加載
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//是不是FactoryBean,這裏確定是不,後續文章會講到FactoryBean和BeanFactory的區別
				if (isFactoryBean(beanName)) {
					//若是是FactoryBean則加上&
					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 {
					//不是FactoryBean直接到這個方法中
					getBean(beanName);
				}
			}
		}

		// 到這裏說明全部的非懶加載的 singleton beans 已經完成了初始化
		// 若是咱們定義的 bean 是實現了 SmartInitializingSingleton 接口的,那麼在這裏獲得回調,忽略
		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();
				}
			}
		}
	}

複製代碼

重點到getBean(beanName)方法中;而初始化的過程也封裝到了這個方法裏。數組

public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
		
   	  /** * 經過 name 獲取 beanName。這裏不使用 name 直接做爲 beanName 有兩個緣由 * 一、name 可能會以 & 字符開頭,代表調用者想獲取 FactoryBean 自己,而非 FactoryBean * 實現類所建立的 bean。在 BeanFactory 中,FactoryBean 的實現類和其餘的 bean 存儲 * 方式是一致的,即 <beanName, bean>,beanName 中是沒有 & 這個字符的。因此咱們須要 * 將 name 的首字符 & 移除,這樣才能獲取到一個傳統的Bean * 二、仍是別名的問題,轉換須要 * &beanName */
		final String beanName = transformedBeanName(name);
        //這個是返回值
		Object bean;

		 /** * 這個方法在初始化的時候會調用,在getBean的時候也會調用 * 爲何須要這麼作呢? * 也就是說spring在初始化的時候先獲取這個對象 * 判斷這個對象是否被實例化好了 * 在初始化時候調用通常都是返回null */
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					//log.....
				}
				else {
					//log.....
				}
			}
            /** * 若是 sharedInstance 是普通的單例 bean,下面的方法會直接返回。但若是 * sharedInstance 是 FactoryBean 類型的,則需調用 getObject 工廠方法獲取真正的 * bean 實例。若是用戶想獲取 FactoryBean 自己,這裏也不會作特別的處理,直接返回 * 便可。畢竟 FactoryBean 的實現類自己也是一種 bean,只不過具備一點特殊的功能而已。 */
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// 檢查原型的bean是否再建立中,若是已經在建立中就拋出異常
            //通常是陷入了循環依賴
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// 檢查一下這個 Bean Definition 在工廠中是否存在
			BeanFactory parentBeanFactory = getParentBeanFactory();//null
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
                // 若是當前容器不存在這個 BeanDefinition,試試父容器中有沒有
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
                //args 是上面傳過來的null
				else if (args != null) {
					// 返回父容器的查詢結果
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
					// No args -> 委託給標準的getBean方法。
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}
			//由於上面parentBeanFactory==null,代碼來到這裏
			if (!typeCheckOnly) {
                //將beanName添加到alreadyCreated set集合當中
				markBeanAsCreated(beanName);
			}
		/* * 稍稍總結一下: * 到這裏的話,要準備建立 Bean 了,對於 singleton 的 Bean 來講,容器中還沒建立過此 Bean; * 對於 prototype 的 Bean 來講,原本就是要建立一個新的 Bean。 */
			try {
                 // 從容器中獲取 beanName 相應的 GenericBeanDefinition,並將其轉換爲 RootBeanDefinition
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                // 檢查給定的合併的 BeanDefinition
				checkMergedBeanDefinition(mbd, beanName, args);
				//檢查dependes-on依賴
				// 先初始化依賴的全部 Bean
              // 注意,這裏的依賴指的是 depends-on 中定義的依賴
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
                     //獲取depends-on的屬性值,若是depends-on的值存在 則添加進入dependentBeanMap緩存中
					for (String dep : dependsOn) {
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(....);
						}
                        // 註冊一下依賴關係
						registerDependentBean(dep, beanName);
						try {
                            // 先初始化被依賴項
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(...);
						}
					}
				}

				// 建立bean實例.
				if (mbd.isSingleton()) {
                    //jdk1.8 Lambda表達式,這裏調用的是getSingleton方法中的getObject方法;
					sharedInstance = getSingleton(beanName, () -> {
						try {
                            // 執行建立 Bean
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				 // 若是是 prototype scope 的,建立 prototype 的實例
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					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(...)....
								
					}
				}
			}
			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.isDebugEnabled()) {
					//log....
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}
複製代碼

在上面這個方法中源碼大概實在315行左右,涉及到jdk1.8新特新Lambda表達式getSingleton();在這個方法中調用了getObject()方法;進入getSingleton()方法中簡單看下:瀏覽器

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
            //當前beanName IndexDaoImpl尚未放入singletonObjects中,因此這裏是null
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
                //檢查是否在銷燬,若是在銷燬就拋出異常
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(.....);
				}
				//log.....
				/** * 將beanName添加到singletonsCurrentlyInCreation這樣一個set集合中 * 表示beanName對應的bean正在建立中 */
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
                    //調用getObject()方法,這個方法其實就是調用上面Lambda表達式中那個createBean()
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					//.......
                    throw ex;
				}
				catch (BeanCreationException ex) {
					//.......
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
                    //把標識爲正在建立的標識去掉
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
                    //向集合中添加數據
                 /** * 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); * } */
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}
複製代碼

咱們接下來看看getObject()方法,上面註釋也說到了getObject()方法中其實就在調用createBean()緩存

接下來咱們重點分析一下 createBean() 方法;app

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
複製代碼

第三個參數 args 數組表明建立實例須要的參數,不就是給構造方法用的參數,或者是工廠 Bean 的參數嘛,不過要注意,在咱們的初始化階段,args 是 null。ide

看類名咱們到了一個新的類 AbstractAutowireCapableBeanFactory,主要是爲了 @Autowired 註解注入屬性值post

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

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

	 // 確保 BeanDefinition 中的 Class 被加載
		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(...);
		}

		try {
			// 在 bean 初始化前應用後置處理,若是後置處理返回的 bean 不爲空,則直接返回
			//這個類須要經過代碼演示
           //這裏執行了bean=applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); 在AOP中使用到能夠返回一個代理對象
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(.....);
		}

		try {
            // 重頭戲
			// 調用doCreateBean 建立bean 
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			//log.....
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(......);
		}
	}
複製代碼

咱們繼續向doCreateBean()方法中看:

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

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			/** * 建立 bean 實例,並將實例包裹在 BeanWrapper 實現類對象中返回。 * createBeanInstance中包含三種建立 bean 實例的方式: * 1. 經過工廠方法建立 bean 實例 * 2. 經過構造方法自動注入(autowire by constructor)的方式建立 bean 實例 * 3. 經過無參構造方法方法建立 bean 實例 * * 若 bean 的配置信息中配置了 lookup-method 和 replace-method,則會使用 CGLIB * 加強 bean 實例。關於lookup-method和replace-method後面再說。 */
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// 建議跳過吧,涉及接口:MergedBeanDefinitionPostProcessor
		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;
			}
		}

		// 下面這塊代碼是爲了解決循環依賴的問題;後續文章會講解到
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				//log....
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			//設置屬性,很是重要
       // 這一步負責屬性裝配,由於前面的實例只是實例化了,並無設值,這裏就是設值
			populateBean(beanName, mbd, instanceWrapper);
			//執行後置處理器,aop就是在這裏完成的處理
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}

		//......省略了一些不重要的代碼

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(.....);
		}

		return exposedObject;
	}
複製代碼

上面這段代碼重點方法是createBeanInstance();

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// 確保已經加載了此 class
		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 對象 * 這種構建 bean 的方式能夠本身寫個demo去試試 * 源碼就不作深刻分析了,有興趣的同窗能夠和我私下討論 */
		if (mbd.getFactoryMethodName() != null)  {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		/** * 從spring的原始註釋能夠知道這個是一個Shortcut,什麼意思呢? * 當屢次構建同一個 bean 時,可使用這個Shortcut, * 也就是說不在須要每次推斷應該使用哪一種方式構造bean * 好比在屢次構建同一個prototype類型的 bean 時,就能夠走此處的Shortcut * 這裏的 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 {
				//經過默認的無參構造方法進行
				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))  {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// No special handling: simply use no-arg constructor.
		//使用默認的無參構造方法進行初始化
		return instantiateBean(beanName, mbd);
	}
複製代碼

咱們看看無參構造是怎麼實例化對象的

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						getInstantiationStrategy().instantiate(mbd, beanName, parent),
						getAccessControlContext());
			}
			else {
				//getInstantiationStrategy()獲得類的實例化策略
				//默認狀況下是獲得一個反射的實例化策略
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			//包裝一下進行返回
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}
複製代碼

關鍵代碼在:

beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

獲得反射的實例化策略以後進入instantiate方法:

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		//檢測 bean 配置中是否配置了 lookup-method 或 replace-method
		//若是配置了就需使用 CGLIB 構建 bean 對象
		if (!bd.hasMethodOverrides()) {
			Constructor<?> constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
					final Class<?> clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(
									(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
						}
						else {
							//獲得無參構造
							constructorToUse =	clazz.getDeclaredConstructor();
						}
						//在這裏給resolvedConstructorOrFactoryMethod賦了值
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			//實例化
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}
複製代碼

進入instantiateClass方法進行實例化:

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
		Assert.notNull(ctor, "Constructor must not be null");
		try {
			// 設置構造方法爲可訪問
			ReflectionUtils.makeAccessible(ctor);
			//反射建立對象
			return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
					KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
		}
複製代碼

這裏就比較簡單了就是使用反射ctor.newInstance(args)進行實例化;這裏拿到實例化以後的Bean返回到:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

中設置屬性,處理依賴

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 {
         // Skip property population phase for null instance.
         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);
}
複製代碼

屬性注入完成後,緊接着就是處理各類回調:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
      // 若是 bean 實現了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回調
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			//執行後置處理的befor
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			//執行bean的聲明週期回調中的init方法
      // 或者若是 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()) {
			//執行後置處理器的after方法
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
複製代碼

BeanPostProcessor 的兩個回調都發生在這邊,只不過中間處理了 init-method

到這裏整個初始化過程就講解完了;下面畫個圖講解一下finishBeanFactoryInitialization方法的整個過程:

由於圖片有點大,我把大縮小了,若是以爲圖片看不清,能夠把地址摳出來,在瀏覽器中看;

image.png
帶中文註釋的Spring源碼,

博客總結

使用博客觀看效果更佳

相關文章
相關標籤/搜索