怎么做網(wǎng)站步驟重慶seo論壇
文章目錄
- 7.11 初始化所有剩下的單實(shí)例bean對(duì)象
- 7.11.1 beanFactory.preInstantiateSingletons
- 7.11.2 getBean
- 7.11.2.1 別名的解析處理
- 7.11.2.2 判斷是否已注冊(cè)過
- 7.11.2.3 創(chuàng)建前的檢查
- 7.11.2.4 標(biāo)記準(zhǔn)備創(chuàng)建的bean對(duì)象
- 7.11.2.5 合并BeanDefinition
- 7.11.2.6 bean對(duì)象的創(chuàng)建
- 7.11.2.7 getSingleton控制單實(shí)例對(duì)象
- 7.11.3 createBean
- 7.11.3.1 resolveBeforeInstantiation
- 7.11.3.2 doCreateBean
- 1.實(shí)例化bean對(duì)象
- (1)解析bean對(duì)象的類型
- (2)處理Supplier創(chuàng)建和工廠方法創(chuàng)建
- (3)原型Bean的創(chuàng)建優(yōu)化
- (4)實(shí)例化bean對(duì)象的真實(shí)動(dòng)作
- 2.屬性賦值前的注解信息收集
- (1)InitDestroyAnnotationBeanPostProcessor
- (2)CommonAnnotationBeanPostProcessor
- (3)AutowiredAnnotationBeanPostProcessor
- 3.早期bean對(duì)象引用的獲取與緩存
- 4.屬性賦值和依賴注入
- (1)回調(diào)InstantiationAwareBeanPostProcessor
- (2)再次回調(diào)InstantiationAwareBeanPostProcessor
- (3)屬性賦值
- 5.bean對(duì)象的初始化
- (1)invokeAwareMethods——執(zhí)行Aware類型接口的回調(diào)
- (2)applyBeanPostProcessorsBeforeInitialization——執(zhí)行BeanPostProcessor的前置回調(diào)
- (3)invokeInitMethods——執(zhí)行初始化生命周期回調(diào)
- (4)applyBeanPostProcessorsAfterInitialization——執(zhí)行BeanPostProcessor的后置回調(diào)
- 6.注冊(cè)銷毀時(shí)的回調(diào)
- 7.11.4 SmartInitializingSingleton
前面四節(jié),詳細(xì)梳理了IOC容器刷新的前面十步(7.1-7.10)以及一個(gè)重要的后置處理器ConfigurationClassPostProcessor,詳見:
SpringBoot源碼解讀與原理分析(二十)IOC容器的刷新(一)
SpringBoot源碼解讀與原理分析(二十一)IOC容器的刷新(二)
SpringBoot源碼解讀與原理分析(二十二)IOC容器的刷新(三)ConfigurationClassPostProcessor
SpringBoot源碼解讀與原理分析(二十三)IOC容器的刷新(四)
這一節(jié)繼續(xù)梳理第十一步(7.11)。
本文超長(zhǎng)預(yù)警,有1400+行。
代碼清單1:AbstractApplicationContext.javapublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.// 7.1 初始化前的預(yù)處理prepareRefresh();// Tell the subclass to refresh the internal bean factory.// 7.2 獲取BeanFactory,加載所有bean的定義信息(未實(shí)例化)ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.// 7.3 BeanFactory的預(yù)處理配置prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.// 7.4 BeanFactory準(zhǔn)備工作完成后的后置處理postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.// 7.5 BeanFactory創(chuàng)建后的后置處理器的執(zhí)行invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.// 7.6 初始化Bean的后置處理器registerBeanPostProcessors(beanFactory);// Initialize message source for this context.// 7.7 初始化MessageSourceinitMessageSource();// Initialize event multicaster for this context.// 7.8 初始化事件廣播器initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.// 7.9 子類擴(kuò)展的刷新動(dòng)作onRefresh();// Check for listener beans and register them.// 7.10 注冊(cè)監(jiān)聽器registerListeners();// 至此,BeanFactory創(chuàng)建完成// Instantiate all remaining (non-lazy-init) singletons.// 7.11 初始化所有剩下的單實(shí)例bean對(duì)象finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.// 7.12 完成容器的創(chuàng)建工作finishRefresh();} catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;} finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...// 7.13 清理緩存resetCommonCaches();}}
}
7.11 初始化所有剩下的單實(shí)例bean對(duì)象
// 7.11 初始化所有剩下的單實(shí)例bean對(duì)象
finishBeanFactoryInitialization(beanFactory);
代碼清單2:AbstractApplicationContext.javaprotected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// 初始化類型轉(zhuǎn)換器ConversionServiceif (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}// 注冊(cè)嵌入式值解析器EmbeddedValueResolverif (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));}// 初始化LoadTimeWeaverAwareString[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}beanFactory.setTempClassLoader(null);// 凍結(jié)配置beanFactory.freezeConfiguration();// 實(shí)例化所有非延遲加載的單實(shí)例BeanbeanFactory.preInstantiateSingletons();
}
由 代碼清單2 可知,finishBeanFactoryInitialization
方法前面的邏輯都是預(yù)備性的,其邏輯重點(diǎn)在最后一行beanFactory.preInstantiateSingletons
:實(shí)例化所有非延遲加載的單實(shí)例Bean。
7.11.1 beanFactory.preInstantiateSingletons
借助IDEA得知,preInstantiateSingletons
方法在ConfigurableListableBeanFactory中定義,最終實(shí)現(xiàn)在DefaultListableBeanFactory中。
代碼清單3:DefaultListableBeanFactory.java@Override
public void preInstantiateSingletons() throws BeansException {// logger...List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);for (String beanName : beanNames) {// 先合并BeanDefinitionRootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);// 不是抽象的、不是延遲加載的單實(shí)例Bean需要初始化if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);// 如果是FactoryBean默認(rèn)不立即初始化if (bean instanceof FactoryBean) {// FactoryBean的處理邏輯}} else {// 普通的Bean的初始化getBean(beanName);}}}// ...
}
由 代碼清單3 可知,在初始化所有非延遲加載的單實(shí)例bean對(duì)象時(shí),會(huì)根據(jù)bean對(duì)象的類型分別處理。如果bean對(duì)象的類型是FactoryBean,會(huì)有單獨(dú)的處理邏輯;而初始化普通bean對(duì)象時(shí),使用的是getBean
方法。
7.11.2 getBean
代碼清單4:AbstractBeanFactory.java@Override
public Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);
}
由 代碼清單4 可知,getBean
方法會(huì)轉(zhuǎn)調(diào)doGetBean
方法。doGetBean
方法的邏輯復(fù)雜,下面拆解來看。
7.11.2.1 別名的解析處理
代碼清單5:AbstractBeanFactory.javaprotected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {// 別名的解析處理String beanName = transformedBeanName(name);// ···
}protected String transformedBeanName(String name) {return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}public String canonicalName(String name) {String canonicalName = name;// Handle aliasing...String resolvedName;do {// 從別名集合中提取真實(shí)的名稱resolvedName = this.aliasMap.get(canonicalName);if (resolvedName != null) {canonicalName = resolvedName;}}while (resolvedName != null);return canonicalName;
}
在使用@Bean注解標(biāo)注在方法上注冊(cè)bean對(duì)象時(shí),可以通過設(shè)置其name或value屬性為bean對(duì)象指定名稱。而name或value屬性可以傳入一個(gè)數(shù)組,意味著一個(gè)bean對(duì)象可以有多個(gè)名稱,默認(rèn)情況下傳入的第一個(gè)屬性值是bean對(duì)象的名稱,其余的都是別名。
代碼清單5 的邏輯就是處理這些別名:如果參數(shù)name是一個(gè)別名,則通過transformedBeanName
方法轉(zhuǎn)換為真正的名稱。
7.11.2.2 判斷是否已注冊(cè)過
代碼清單6:AbstractBeanFactory.javaprotected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {// ···// 先嘗試從已經(jīng)實(shí)例化好的Bean中找有沒有當(dāng)前Bean// 如果能找到,說明Bean已經(jīng)被實(shí)例化了,直接返回Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {// logger ......bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);} else// ···
}protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {// ...// 如果不是FactoryBean,直接返回if (!(beanInstance instanceof FactoryBean)) {return beanInstance;}// ...// 如果是FactoryBean,則調(diào)用getObject方法獲取對(duì)象object = getObjectFromFactoryBean(factory, beanName, !synthetic);return object;
}
}
由 代碼清單6 可知,第二步是嘗試獲取IOC容器中是否已創(chuàng)建并緩存當(dāng)前正在獲取的單實(shí)例bean對(duì)象,如果成功獲取到,說明Bean已經(jīng)被實(shí)例化了,直接返回。getObjectForBeanInstance
方法對(duì)返回的結(jié)果進(jìn)行分類處理,如果獲取到的bean對(duì)象是一個(gè)FactoryBean,則進(jìn)行一些額外處理,并通過調(diào)用getObject
方法獲取對(duì)象;如果是普通的bean對(duì)象,則直接返回。
7.11.2.3 創(chuàng)建前的檢查
如果 代碼清單6 中沒有獲取到bean對(duì)象,說明當(dāng)前處理的Bean還未創(chuàng)建,即if邏輯判斷為false,則進(jìn)入else結(jié)構(gòu)部分,開始創(chuàng)建該bean對(duì)象。
代碼清單7:AbstractBeanFactory.javaprotected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {// ···else {// 如果當(dāng)前創(chuàng)建的bean對(duì)象是一個(gè)原型Bean并且正在創(chuàng)建,拋出異常if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}BeanFactory parentBeanFactory = getParentBeanFactory();// 如果當(dāng)前BeanFactory沒有當(dāng)前bean對(duì)象的BeanDefinition// 則通過父級(jí)BeanFactory返回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);}}}// ···
}
由 代碼清單7 可知,創(chuàng)建bean對(duì)象之前會(huì)進(jìn)行校驗(yàn),判斷當(dāng)前要?jiǎng)?chuàng)建的bean對(duì)象是否是一個(gè)原型Bean并且已經(jīng)在創(chuàng)建了,如果是,說明當(dāng)前原型Bean在一次獲取中將產(chǎn)生兩個(gè)對(duì)象,這種現(xiàn)象不合理,所以會(huì)拋出異常。
第二項(xiàng)校驗(yàn)是判斷當(dāng)前BeanFactory是否包含當(dāng)前bean對(duì)象的BeanDefinition,如果沒有,則通過父級(jí)BeanFactory的doGetBean
方法或getBean
方法返回(BeanFactory的層次性的體現(xiàn))。
7.11.2.4 標(biāo)記準(zhǔn)備創(chuàng)建的bean對(duì)象
代碼清單8:AbstractBeanFactory.javaprotected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {// ···else {// ...if (!typeCheckOnly) {markBeanAsCreated(beanName);}// ...}// ···
}protected void markBeanAsCreated(String beanName) {if (!this.alreadyCreated.contains(beanName)) {synchronized (this.mergedBeanDefinitions) {if (!this.alreadyCreated.contains(beanName)) {clearMergedBeanDefinition(beanName);this.alreadyCreated.add(beanName);}}}
}
由 代碼清單8 可知,在確認(rèn)Bean確需創(chuàng)建之后,會(huì)對(duì)其名稱進(jìn)行標(biāo)記。markBeanAsCreated
方法會(huì)將當(dāng)前正在處理的bean對(duì)象的名稱放入alreadyCreated集合中,代表該bean對(duì)象已被創(chuàng)建。
7.11.2.5 合并BeanDefinition
代碼清單9:AbstractBeanFactory.javaprotected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {// ···else {// ...try {// 合并BeanDefinitionRootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// 處理當(dāng)前bean對(duì)象的依賴(@DependsOn注解)String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) {// 注冊(cè)并初始化依賴的bean對(duì)象registerDependentBean(dep, beanName);try {getBean(dep);} // catch ...}}}// ...} // catch...}// ···
}
由 代碼清單9 可知,合并BeanDefinition的getMergedLocalBeanDefinition
方法可以得到當(dāng)前正在創(chuàng)建的bean對(duì)象需要依賴哪些bean對(duì)象,也就是在當(dāng)前創(chuàng)建的bean對(duì)象中顯式標(biāo)注了@DependsOn注解的屬性。
由于標(biāo)注了@DependsOn注解的屬性代表強(qiáng)制依賴,IOC容器會(huì)優(yōu)先處理這些被強(qiáng)制依賴的bean對(duì)象并將其初始化,而初始化的方式依然是getBean
方法。
7.11.2.6 bean對(duì)象的創(chuàng)建
代碼清單10:AbstractBeanFactory.javaprotected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {// ···else {// ...try {// ...// 單實(shí)例singleton作用域if (mbd.isSingleton()) {// 每次調(diào)用createBean返回的都是同一個(gè)實(shí)例sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);} // catch...});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);} // 原型prototype作用域else if (mbd.isPrototype()) {// 每次調(diào)用createBean都會(huì)創(chuàng)建一個(gè)新的實(shí)例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();// ...try {Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);} finally {afterPrototypeCreation(beanName);}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);} // catch...}} // catch...}// ···
}
由 代碼清單10 可知,經(jīng)過多步的檢查和前置處理之后,bean對(duì)象終于開始創(chuàng)建。IOC容器會(huì)根據(jù)當(dāng)前正在創(chuàng)建的bean對(duì)象的作用域(單實(shí)例singleton作用域、原型prototype作用域或其他)決定如何創(chuàng)建對(duì)象。
但不管是哪些作用域,底層都是調(diào)用createBean
方法創(chuàng)建對(duì)象。不同的是,對(duì)于單實(shí)例singleton作用域,每次調(diào)用createBean
方法返回的都是同一個(gè)實(shí)例;對(duì)于原型prototype作用域,每次調(diào)用createBean
方法都會(huì)創(chuàng)建一個(gè)新的實(shí)例。
IOC容器中控制單實(shí)例對(duì)象的方式是使用getSingleton
方法配合ObjectFactory實(shí)現(xiàn)的。
7.11.2.7 getSingleton控制單實(shí)例對(duì)象
代碼清單11:DefaultSingletonBeanRegistry.javaprivate final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");synchronized (this.singletonObjects) {// 加鎖后,從緩存集合中提取bean對(duì)象實(shí)例Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {// 如果緩存中沒有,則創(chuàng)建對(duì)象if (this.singletonsCurrentlyInDestruction) {// throw ...}if (logger.isDebugEnabled()) {// logger ...}beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();}try {// 調(diào)用getObject方法就是外層調(diào)用createBean方法singletonObject = singletonFactory.getObject();newSingleton = true;} // catch finally...// 新創(chuàng)建的單實(shí)例bean對(duì)象存入緩存中if (newSingleton) {addSingleton(beanName, singletonObject);}}return singletonObject;}
}
由 代碼清單11 可知,控制單實(shí)例bean對(duì)象的方式借助一個(gè)名為singletonObjects的Map集合充當(dāng)緩存區(qū),在獲取單實(shí)例bean對(duì)象時(shí),會(huì)先從緩存區(qū)中嘗試獲取,如果沒有獲取到則會(huì)調(diào)用createBean
方法創(chuàng)建對(duì)象,并保存到singletonObjects緩存中。
簡(jiǎn)言之,單實(shí)例bean對(duì)象在第一次創(chuàng)建時(shí)會(huì)調(diào)用createBean
方法真正地創(chuàng)建對(duì)象,創(chuàng)建完畢會(huì)存入IOC容器底層的singletonObjects緩存區(qū),后續(xù)再次獲取時(shí)會(huì)直接從緩存區(qū)中取出bean對(duì)象并返回。
7.11.3 createBean
代碼清單12:AbstractAutowireCapableBeanFactory.javaprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// logger ...}RootBeanDefinition mbdToUse = mbd;// 根據(jù)BeanDefinition獲取當(dāng)前正在創(chuàng)建的bean對(duì)象的類型Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// ...try {// 后置處理器BeanPostProcessors攔截創(chuàng)建bean對(duì)象Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}} // catch ...try {// 真正創(chuàng)建bean對(duì)象Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;} // catch ...
}
由 代碼清單12 可知,實(shí)際創(chuàng)建bean對(duì)象有兩個(gè)切入點(diǎn):
- 通過
resolveBeforeInstantiation
方法創(chuàng)建bean對(duì)象:由方法名可以理解為“實(shí)例化之前的處理”,因此這只是創(chuàng)建bean對(duì)象之前的攔截。 - 通過
doCreateBean
方法實(shí)際創(chuàng)建bean對(duì)象。
7.11.3.1 resolveBeforeInstantiation
代碼清單13:AbstractAutowireCapableBeanFactory.javaprotected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// Make sure bean class is actually resolved at this point.if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {// 執(zhí)行所有InstantiationAwareBeanPostProcessorbean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {// 如果成功創(chuàng)建了bean對(duì)象,則執(zhí)行所有的BeanPostProcessorsbean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;
}protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {// 循環(huán)找出所有的InstantiationAwareBeanPostProcessorfor (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;// 調(diào)用其postProcessBeforeInstantiation方法實(shí)例化對(duì)象Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);if (result != null) {return result;}}}return null;
}@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;// 循環(huán)找出所有的BeanPostProcessorfor (BeanPostProcessor processor : getBeanPostProcessors()) {// 調(diào)用其postProcessAfterInitialization方法增強(qiáng)對(duì)象Object current = processor.postProcessAfterInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;
}
由 代碼清單14 可知,攔截bean對(duì)象的創(chuàng)建行為有兩步:先執(zhí)行所有InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation
方法創(chuàng)建對(duì)象,如果成功創(chuàng)建bean對(duì)象,在執(zhí)行所有BeanPostProcessors的postProcessAfterInitialization
方法增強(qiáng)對(duì)象。
以上兩個(gè)后置處理器的底層邏輯基本一致,都是從IOC容器獲取到所有注冊(cè)的后置處理器,并逐一回調(diào)。
7.11.3.2 doCreateBean
如果resolveBeforeInstantiation
方法沒有創(chuàng)建出bean對(duì)象,則需要執(zhí)行doCreateBean
方法創(chuàng)建bean對(duì)象的實(shí)例。doCreateBean
方法的邏輯非常長(zhǎng),下面拆解來看。
1.實(shí)例化bean對(duì)象
代碼清單14:AbstractAutowireCapableBeanFactory.javaprotected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// ...if (instanceWrapper == null) {// 創(chuàng)建bean對(duì)象實(shí)例instanceWrapper = createBeanInstance(beanName, mbd, args);}// 得到bean對(duì)象的引用Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// ...
}
由 代碼清單14 可知,實(shí)例化bean對(duì)象是創(chuàng)建對(duì)象的第一步,即createBeanInstance
方法。
(1)解析bean對(duì)象的類型
代碼清單15:AbstractAutowireCapableBeanFactory.javaprotected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// 解析出bean對(duì)象的類型Class<?> beanClass = resolveBeanClass(mbd, beanName);// 如果bean對(duì)象無法被訪問,則拋出異常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());}// ...
}
由 代碼清單15 可知,createBeanInstance
方法首先會(huì)檢驗(yàn)當(dāng)前要?jiǎng)?chuàng)建的bean對(duì)象所屬類型是否可以被正常訪問,如果不可以,則會(huì)拋出異常。
(2)處理Supplier創(chuàng)建和工廠方法創(chuàng)建
代碼清單16:AbstractAutowireCapableBeanFactory.javaprotected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// ...//如果制定了實(shí)例Supplier,則通過Supplier實(shí)例化bean對(duì)象Supplier<?> instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);}// 如果指定了工廠方法,則通過工廠方法實(shí)例化bean對(duì)象if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}// ...
}/*** Obtain a bean instance from the given supplier.*/
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
由 代碼清單16 可知,如果BeanDefinition中指定了實(shí)例Supplier,則通過Supplier實(shí)例化bean對(duì)象。obtainFromSupplier
方法的 javadoc 指出,這個(gè)方法可以從給定的Supplier中得到bean實(shí)例。
如果BeanDefinition中指定了工廠方法,則通過工廠方法實(shí)例化bean對(duì)象。
(3)原型Bean的創(chuàng)建優(yōu)化
代碼清單17:AbstractAutowireCapableBeanFactory.javaprotected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// ...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) {// 直接從BeanDefinition中取出構(gòu)造方法以實(shí)例化對(duì)象return autowireConstructor(beanName, mbd, null, null);}else {// 通過構(gòu)造方法實(shí)例化對(duì)象return instantiateBean(beanName, mbd);}}// ...
}
由 代碼清單17 可知,這一段代碼是針對(duì)原型Bean而言的,在第一次原型bean對(duì)象創(chuàng)建完成后,將創(chuàng)建過程中引用的構(gòu)造方法緩存到BeanDefinition中,以備后續(xù)創(chuàng)建時(shí)可以直接取出。
(4)實(shí)例化bean對(duì)象的真實(shí)動(dòng)作
代碼清單18:AbstractAutowireCapableBeanFactory.javaprotected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// ...// 回調(diào)SmartInstantiationAwareBeanPostProcessor尋找構(gòu)造方法Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);// 條件1:通過SmartInstantiationAwareBeanPostProcessor找到了構(gòu)造方法// 條件2:配置自動(dòng)注入方式為AUTOWIRE_CONSTRUCTOR// 條件3:使用XML配置文件的方式定義Bean時(shí)指定了constructor-arg標(biāo)簽// 條件4:調(diào)用getBean方法獲取bean對(duì)象時(shí)傳入了args參數(shù)if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {// 使用顯式構(gòu)造方法實(shí)例化bean對(duì)象return autowireConstructor(beanName, mbd, ctors, args);}// 如果BeanDefinition中指定了首選構(gòu)造函數(shù),也使用顯式構(gòu)造方法實(shí)例化bean對(duì)象ctors = mbd.getPreferredConstructors();if (ctors != null) {return autowireConstructor(beanName, mbd, ctors, null);}// 使用無參數(shù)構(gòu)造方法實(shí)例化bean對(duì)象return instantiateBean(beanName, mbd);
}
由 代碼清單18 可知,當(dāng)觸發(fā)一些條件時(shí),IOC容器會(huì)選擇使用顯式構(gòu)造方法實(shí)例化bean對(duì)象。
- 條件1:通過SmartInstantiationAwareBeanPostProcessor找到了構(gòu)造方法;
- 條件2:配置自動(dòng)注入方式為AUTOWIRE_CONSTRUCTOR;
- 條件3:使用XML配置文件的方式定義Bean時(shí)指定了constructor-arg標(biāo)簽;
- 條件4:調(diào)用getBean方法獲取bean對(duì)象時(shí)傳入了args參數(shù);
- 條件5:BeanDefinition中指定了首選構(gòu)造函數(shù)。
如果以上條件都不滿足,則會(huì)使用默認(rèn)的無參構(gòu)造方法創(chuàng)建對(duì)象。
代碼清單19:AbstractAutowireCapableBeanFactory.javaprotected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {try {Object beanInstance;// 借助InstantiationStrategy實(shí)例化對(duì)象if (System.getSecurityManager() != null) {beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),getAccessControlContext());} else {beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);}BeanWrapper bw = new BeanWrapperImpl(beanInstance);initBeanWrapper(bw);return bw;} // catch ...
}@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {// ...return BeanUtils.instantiateClass(constructorToUse);
}
由 代碼清單19 可知,instantiateBean
的重點(diǎn)在于獲取InstantiationStrategy,使用BeanUtils.instantiateClass
方法反射實(shí)例化bean對(duì)象。
經(jīng)過createBeanInstance
方法后,即可得到一個(gè)對(duì)象內(nèi)部沒有任何額外注入的bean對(duì)象,bean對(duì)象的實(shí)例化完畢。
2.屬性賦值前的注解信息收集
回到doCreateBean
方法,實(shí)例化bean對(duì)象之后,進(jìn)入屬性賦值前的注解信息收集。
代碼清單20:AbstractAutowireCapableBeanFactory.javaprotected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// ...synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);} // catch ...mbd.postProcessed = true;}}// ...
}protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof MergedBeanDefinitionPostProcessor) {MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);}}
}
由 代碼清單20 可知,核心方法applyMergedBeanDefinitionPostProcessors
會(huì)回調(diào)所有的MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition
方法。借助IDEA可知,有幾個(gè)重要的后置處理器實(shí)現(xiàn)了該方法。
(1)InitDestroyAnnotationBeanPostProcessor
代碼清單21:InitDestroyAnnotationBeanPostProcessor.java@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {LifecycleMetadata metadata = findLifecycleMetadata(beanType);metadata.checkConfigMembers(beanDefinition);
}private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {// ...return buildLifecycleMetadata(clazz);
}private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {// ...List<LifecycleElement> initMethods = new ArrayList<>();List<LifecycleElement> destroyMethods = new ArrayList<>();Class<?> targetClass = clazz;do {final List<LifecycleElement> currInitMethods = new ArrayList<>();final List<LifecycleElement> currDestroyMethods = new ArrayList<>();// 反射所有的public方法ReflectionUtils.doWithLocalMethods(targetClass, method -> {// 尋找所有被@PostConstruct注解標(biāo)注的方法if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {LifecycleElement element = new LifecycleElement(method);currInitMethods.add(element);// logger ...}// 尋找所有被@PostDestroy注解標(biāo)注的方法if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {currDestroyMethods.add(new LifecycleElement(method));// logger ...}});initMethods.addAll(0, currInitMethods);destroyMethods.addAll(currDestroyMethods);// 依次向上尋找父類targetClass = targetClass.getSuperclass();}while (targetClass != null && targetClass != Object.class);// return ...
}
由 代碼清單21 可知,postProcessMergedBeanDefinition
方法會(huì)掃描和收集當(dāng)前正在創(chuàng)建的bean對(duì)象中標(biāo)注了@PostConstruct注解和@PostDestroy注解的方法。源碼中的initAnnotationType對(duì)應(yīng)@PostConstruct注解,destroyAnnotationType對(duì)應(yīng)@PostDestroy注解。
(2)CommonAnnotationBeanPostProcessor
代碼清單22:CommonAnnotationBeanPostProcessor.java@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {// 調(diào)用父類InitDestroyAnnotationBeanPostProcessor的postProcessMergedBeanDefinition方法super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);metadata.checkConfigMembers(beanDefinition);
}private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) {// ...metadata = buildResourceMetadata(clazz);// ...
}private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {// ...do {final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();ReflectionUtils.doWithLocalFields(targetClass, field -> {// @WebServiceRefif (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {if (Modifier.isStatic(field.getModifiers())) {throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");}currElements.add(new WebServiceRefElement(field, field, null));} // @EJBelse if (ejbClass != null && field.isAnnotationPresent(ejbClass)) {if (Modifier.isStatic(field.getModifiers())) {throw new IllegalStateException("@EJB annotation is not supported on static fields");}currElements.add(new EjbRefElement(field, field, null));} // @Resourceelse if (field.isAnnotationPresent(Resource.class)) {if (Modifier.isStatic(field.getModifiers())) {throw new IllegalStateException("@Resource annotation is not supported on static fields");}if (!this.ignoredResourceTypes.contains(field.getType().getName())) {currElements.add(new ResourceElement(field, field, null));}}});// ...elements.addAll(0, currElements);// 依次向上尋找父類targetClass = targetClass.getSuperclass();}while (targetClass != null && targetClass != Object.class);return InjectionMetadata.forElements(elements, clazz);
}
由 代碼清單22 可知,CommonAnnotationBeanPostProcessor的父類是InitDestroyAnnotationBeanPostProcessor,所以它也具備收集@PostConstruct注解和@PostDestroy注解的能力,同時(shí)還具備收集JSR-250規(guī)范中的注解(如@WebServiceRef、@EJB、 @Resource)的能力。
(3)AutowiredAnnotationBeanPostProcessor
代碼清單23:AutowiredAnnotationBeanPostProcessor.javapublic AutowiredAnnotationBeanPostProcessor() {this.autowiredAnnotationTypes.add(Autowired.class);this.autowiredAnnotationTypes.add(Value.class);try {this.autowiredAnnotationTypes.add((Class<? extends Annotation>)ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");} // catch ...
}@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);metadata.checkConfigMembers(beanDefinition);
}
由 代碼清單24 可知,AutowiredAnnotationBeanPostProcessor具備的能力是收集@Autowired、@Value、@Inject注解,收集原理和前面兩者后置處理器的原理一致。
3.早期bean對(duì)象引用的獲取與緩存
回到doCreateBean
方法,收集完屬性賦值前的注解信息之后,開始收集早期bean對(duì)象引用。
代碼清單25:AbstractAutowireCapableBeanFactory.javaprotected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// ...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");}// 處理循環(huán)依賴的問題addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// ...
}
由 代碼清單25 可知,bean對(duì)象實(shí)例化之后,雖然沒有進(jìn)行屬性賦值和依賴注入,但也已經(jīng)是一個(gè)實(shí)實(shí)在在的對(duì)象。如果在此期間有另外的bean對(duì)象需要依賴它,就不應(yīng)該再創(chuàng)建一個(gè)新的bean對(duì)象,而是直接獲取當(dāng)前bean對(duì)象的引用即可。
這個(gè)設(shè)計(jì)就是為了解決bean對(duì)象之間的循環(huán)依賴。
4.屬性賦值和依賴注入
回到doCreateBean
方法,處理早期bean對(duì)象引用之后,開始進(jìn)行屬性賦值和依賴注入。
代碼清單26:AbstractAutowireCapableBeanFactory.javaprotected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// ...// Initialize the bean instance.Object exposedObject = bean;try {// 屬性賦值和依賴注入populateBean(beanName, mbd, instanceWrapper);// bean對(duì)象的初始化exposedObject = initializeBean(beanName, exposedObject, mbd);} // catch ...// ...
}
(1)回調(diào)InstantiationAwareBeanPostProcessor
代碼清單27:AbstractAutowireCapableBeanFactory.javaprotected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {// 前置檢查 ...// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the// state of the bean before properties are set. This can be used, for example,// to support styles of field injection.// 在設(shè)置屬性之前,讓任何InstantiationAwareBeanPostProcessors都有機(jī)會(huì)修改// Bean的狀態(tài),例如支持屬性字段的注入。if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}}}}// ...
由 代碼清單27 可知,InstantiationAwareBeanPostProcessors是一個(gè)可以干預(yù)Bean的屬性、狀態(tài)等信息的后置處理器。其postProcessAfterInstantiation
方法的返回值是boolean類型,當(dāng)返回false時(shí)直接結(jié)束populateBean
方法,不再執(zhí)行真正的屬性賦值+組件依賴注入的邏輯。
這樣設(shè)計(jì)的目的在于,允許開發(fā)者在bean對(duì)象已經(jīng)實(shí)例化完畢但還沒有開始屬性賦值和依賴注入時(shí)切入自定義邏輯。
(2)再次回調(diào)InstantiationAwareBeanPostProcessor
代碼清單28:AbstractAutowireCapableBeanFactory.javaprotected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {// ...for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);// ...}}// ...
由 代碼清單28 可知,populateBean
方法會(huì)再一次回調(diào)InstantiationAwareBeanPostProcessor,但這次調(diào)用的是其postProcessProperties
方法,作用是執(zhí)行組件的依賴注入。
負(fù)責(zé)依賴注入的后置處理器是前面提到的AutowiredAnnotationBeanPostProcessor。
代碼清單29:AutowiredAnnotationBeanPostProcessor.java@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);try {metadata.inject(bean, beanName, pvs);} // catch ...
}public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {Collection<InjectedElement> checkedElements = this.checkedElements;// 取出在前面收集的@Autowired、@Value、@Inject注解Collection<InjectedElement> elementsToIterate =(checkedElements != null ? checkedElements : this.injectedElements);if (!elementsToIterate.isEmpty()) {// 逐個(gè)注入for (InjectedElement element : elementsToIterate) {element.inject(target, beanName, pvs);}}
}
由 代碼清單29 可知,在進(jìn)行依賴注入時(shí),首先會(huì)取出前面步驟收集的所有標(biāo)注了@Autowired、@Value、@Inject注解的方法,封裝為InjectionMetadata,并調(diào)用其inject
方法進(jìn)行依賴注入。
(3)屬性賦值
代碼清單30:AbstractAutowireCapableBeanFactory.javaprotected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {// ...PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);// ...if (needsDepCheck) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}checkDependencies(beanName, mbd, filteredPds, pvs);}if (pvs != null) {// 應(yīng)用PropertyValues對(duì)象到當(dāng)前正在創(chuàng)建的bean對(duì)象applyPropertyValues(beanName, mbd, bw, pvs);}
由 代碼清單30 可知,經(jīng)過前面幾個(gè)步驟之后,生成了一個(gè)PropertyValues對(duì)象,該對(duì)象封裝了當(dāng)前正在創(chuàng)建的bean對(duì)象中需要依賴的所有屬性賦值類元素,最后執(zhí)行的applyPropertyValues
方法就是把前面準(zhǔn)備好的PropertyValues對(duì)象封裝的內(nèi)容應(yīng)用到當(dāng)前正在創(chuàng)建的bean對(duì)象實(shí)例中。
在applyPropertyValues
方法內(nèi)部,會(huì)將屬性值反射注入bean對(duì)象的成員屬性中。
經(jīng)過該階段,bean對(duì)象的屬性賦值和依賴注入工作完成。
5.bean對(duì)象的初始化
由 代碼清單26 可知,屬性賦值和依賴注入完成后,立刻開始初始化bean對(duì)象,即initializeBean
方法。
代碼清單31:AbstractAutowireCapableBeanFactory.javaprotected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {// 執(zhí)行Aware類型接口的回調(diào)invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());} else {invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {// 執(zhí)行BeanPostProcessor的前置回調(diào)wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {// 執(zhí)行生命周期回調(diào)invokeInitMethods(beanName, wrappedBean, mbd);} // catch ...if (mbd == null || !mbd.isSynthetic()) {// 執(zhí)行BeanPostProcessor的后置回調(diào)wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}
由 代碼清單31 可知,initializeBean
方法包含4個(gè)回調(diào)邏輯。
(1)invokeAwareMethods——執(zhí)行Aware類型接口的回調(diào)
代碼清單32:AbstractAutowireCapableBeanFactory.javaprivate void invokeAwareMethods(String beanName, Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {ClassLoader bcl = getBeanClassLoader();if (bcl != null) {((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);}}if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}
}
由 代碼清單32 可知,invokeAwareMethods
方法會(huì)判斷當(dāng)前bean對(duì)象是否實(shí)現(xiàn)了特定的Aware接口,如果實(shí)現(xiàn)了就強(qiáng)轉(zhuǎn)后掉喲個(gè)對(duì)應(yīng)的setter方法。
(2)applyBeanPostProcessorsBeforeInitialization——執(zhí)行BeanPostProcessor的前置回調(diào)
代碼清單33:AbstractAutowireCapableBeanFactory.javapublic Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessBeforeInitialization(result, beanName);// 如果一個(gè)BeanPostProcessor處理bean對(duì)象后返回的結(jié)果為null// 則不再執(zhí)行剩余的BeanPostProcessor// 而直接返回上一個(gè)BeanPostProcessor處理之后的bean對(duì)象if (current == null) {return result;}result = current;}return result;
}
由 代碼清單33 可知,該回調(diào)邏輯是執(zhí)行BeanPostProcessor的postProcessBeforeInitialization
方法。
在這中間有一個(gè)特殊的設(shè)計(jì):如果一個(gè)BeanPostProcessor處理bean對(duì)象后返回的結(jié)果為null,則不再執(zhí)行剩余的BeanPostProcessor,而直接返回上一個(gè)BeanPostProcessor處理之后的bean對(duì)象。這樣設(shè)計(jì)的目的,是方便開發(fā)者在設(shè)計(jì)postProcessBeforeInitialization
方法時(shí),可以通過控制其返回值以進(jìn)行特殊處理。
下面介紹兩個(gè)后置處理器實(shí)現(xiàn)類。
- InitDestroyAnnotationBeanPostProcessor
代碼清單34:InitDestroyAnnotationBeanPostProcessor.java@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// 收集標(biāo)注了@PostConstruct和@PreDestroy的方法InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());try {// 執(zhí)行初始化方法metadata.invokeInitMethods(bean, beanName);} // catch ...return bean;
}public void invokeInitMethods(Object target, String beanName) throws Throwable {Collection<InitDestroyAnnotationBeanPostProcessor.LifecycleElement> checkedInitMethods = this.checkedInitMethods;Collection<InitDestroyAnnotationBeanPostProcessor.LifecycleElement> initMethodsToIterate =(checkedInitMethods != null ? checkedInitMethods : this.initMethods);if (!initMethodsToIterate.isEmpty()) {for (InitDestroyAnnotationBeanPostProcessor.LifecycleElement element : initMethodsToIterate) {// logger ...element.invoke(target);}}
}public void invoke(Object target) throws Throwable {ReflectionUtils.makeAccessible(this.method);this.method.invoke(target, (Object[]) null);
}
由 代碼清單34 可知,postProcessBeforeInitialization
方法首先會(huì)收集標(biāo)注了@PostConstruct和@PreDestroy的方法(收集方法詳見【7.11.3.2 2.屬性賦值前的注解信息收集 (1)InitDestroyAnnotationBeanPostProcessor】),然后回調(diào)bean對(duì)象中所有標(biāo)注了@PostConstruct注解的方法。
由ReflectionUtils.makeAccessible(this.method);
可知,反射執(zhí)行目標(biāo)方法時(shí)會(huì)先借助ReflectionUtils獲取其訪問權(quán),這意味著對(duì)于使用@PostConstruct注解標(biāo)注的方法的訪問修飾符沒有強(qiáng)限制。
由this.method.invoke(target, (Object[]) null);
可知,最終回調(diào)方法時(shí)傳入的參數(shù)時(shí)空對(duì)象,這也解釋了為什么在使用@PostConstruct注解標(biāo)注方法時(shí)一定要設(shè)置為空參數(shù)方法。
- ApplicationContextAwareProcessor
代碼清單35:ApplicationContextAwareProcessor.java@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// 不是這6個(gè)Aware子接口的,不予處理if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){return bean;}// ...else {invokeAwareInterfaces(bean);}return bean;
}private void invokeAwareInterfaces(Object bean) {if (bean instanceof EnvironmentAware) {((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());}if (bean instanceof EmbeddedValueResolverAware) {((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);}if (bean instanceof ResourceLoaderAware) {((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);}if (bean instanceof ApplicationEventPublisherAware) {((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);}if (bean instanceof MessageSourceAware) {((MessageSourceAware) bean).setMessageSource(this.applicationContext);}if (bean instanceof ApplicationContextAware) {((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);}
}
由 代碼清單35 可知,ApplicationContextAwareProcessor支持6個(gè)Aware子接口的回調(diào)注入,否則不予處理。執(zhí)行Aware子接口時(shí)根據(jù)不同類型執(zhí)行setter方法。
(3)invokeInitMethods——執(zhí)行初始化生命周期回調(diào)
代碼清單36:AbstractAutowireCapableBeanFactory.javaprotected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {boolean isInitializingBean = (bean instanceof InitializingBean);if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {// ...} else {// 回調(diào)InitializingBean的afterPropertiesSet方法((InitializingBean) bean).afterPropertiesSet();}}if (mbd != null && bean.getClass() != NullBean.class) {String initMethodName = mbd.getInitMethodName();if (StringUtils.hasLength(initMethodName) &&!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.isExternallyManagedInitMethod(initMethodName)) {// 反射回調(diào)init-method方法invokeCustomInitMethod(beanName, bean, mbd);}}
}
由 代碼清單36 可知,初始化生命周期回調(diào)包括init-method方法和InitializingBean接口的初始化邏輯回調(diào)。
(4)applyBeanPostProcessorsAfterInitialization——執(zhí)行BeanPostProcessor的后置回調(diào)
代碼清單37:AbstractAutowireCapableBeanFactory.java@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessAfterInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;
}
由 代碼清單37 可知,回調(diào)BeanPostProcessor的后置攔截的邏輯和前置攔截幾乎一致。重點(diǎn)關(guān)注兩個(gè)后置處理器的實(shí)現(xiàn)。
- AbstractAutoProxyCreator
所有以AutoProxyCreator結(jié)尾的類都與AOP相關(guān),且都是具備代理對(duì)象創(chuàng)建能力的后置處理器,可以在bean對(duì)象本身的初始化邏輯完成后根據(jù)需要?jiǎng)?chuàng)建代理對(duì)象。
- ApplicationListenerDetector
ApplicationListenerDetector的作用是關(guān)聯(lián)事件廣播器和監(jiān)聽器的引用,因此在創(chuàng)建ApplicationListener類型的bean對(duì)象時(shí),ApplicationListenerDetector會(huì)檢測(cè)并將其添加到ApplicationContext中,關(guān)聯(lián)ApplicationEventMulticaster事件廣播器。
6.注冊(cè)銷毀時(shí)的回調(diào)
回到doCreateBean
方法,bean對(duì)象初始化之后,最后一步是注冊(cè)銷毀時(shí)的回調(diào)。
代碼清單38:AbstractAutowireCapableBeanFactory.javaprotected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// ...try {// 注冊(cè)銷毀時(shí)的回調(diào)registerDisposableBeanIfNecessary(beanName, bean, mbd);} // catch ...// ...
}protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);// 不是原型Bean,且定義了銷毀類型的方法if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {if (mbd.isSingleton()) {// 注冊(cè)一個(gè)執(zhí)行給定bean對(duì)象的所有銷毀工作的DisposableBean實(shí)現(xiàn):Destruction// 通過實(shí)現(xiàn)DisposableBean接口,或自定義銷毀方法。registerDisposableBean(beanName,new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));} // else...}
}
由 代碼清單38 可知,如果一個(gè)bean對(duì)象的所屬類型實(shí)現(xiàn)了DisposableBean接口,或者內(nèi)部方法中標(biāo)注了@PreDestory注解,或者聲明了destory-method方法,則會(huì)在doCreateBean
方法的最后階段注冊(cè)一個(gè)銷毀bean對(duì)象的回調(diào)鉤子,在IOC容器關(guān)閉時(shí),這部分bean對(duì)象會(huì)回調(diào)其自定義的自毀邏輯。
至此,doCreateBean
方法執(zhí)行完畢,一個(gè)bean對(duì)象被創(chuàng)建完成并返回。
7.11.4 SmartInitializingSingleton
回到preInstantiateSingletons
方法,在bean對(duì)象創(chuàng)建完成后,還有一段額外的邏輯。
代碼清單39:DefaultListableBeanFactory.java@Override
public void preInstantiateSingletons() throws BeansException {// ...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();}}}
}
由 代碼清單39 可知,如果bean對(duì)象實(shí)現(xiàn)了SmartInitializingSingleton接口,則遍歷回調(diào)其afterSingletonsInstantiated
方法。這實(shí)際上是在非延遲加載的單實(shí)例bean對(duì)象全部創(chuàng)建完成后提供一個(gè)統(tǒng)一的擴(kuò)展回調(diào)時(shí)機(jī),以便在ApplicationContext初始化完成之前處理一些特殊的邏輯。
經(jīng)過上述一系列復(fù)雜邏輯后,finishBeanFactoryInitialization
方法執(zhí)行完畢,所有非延遲加載的單實(shí)例bean對(duì)象全部完成創(chuàng)建并初始化。
······
至此,IOC容器的刷新完成了前面十一步,分別是:
7.1 初始化前的預(yù)處理
7.2 初始化BeanFactory
7.3 BeanFactory的預(yù)處理配置
7.4 BeanFactory準(zhǔn)備工作完成后的后置處理
7.5 BeanFactory創(chuàng)建后的后置處理器的執(zhí)行
7.6 初始化Bean的后置處理器
7.7 初始化國(guó)際化組件
7.8 初始化事件廣播器
7.9 子類擴(kuò)展的刷新動(dòng)作
7.10 注冊(cè)監(jiān)聽器
7.11 初始化所有剩下的單實(shí)例bean對(duì)象
本節(jié)完,更多內(nèi)容請(qǐng)查閱分類專欄:SpringBoot源碼解讀與原理分析