中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

怎么做網(wǎng)站步驟重慶seo論壇

怎么做網(wǎng)站步驟,重慶seo論壇,英國(guó)政府網(wǎng)站建設(shè)的特點(diǎn),幼兒園門戶網(wǎng)站建設(shè)文章目錄 7.11 初始化所有剩下的單實(shí)例bean對(duì)象7.11.1 beanFactory.preInstantiateSingletons7.11.2 getBean7.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 合并BeanDefinition7.11.2.6 bean對(duì)象的創(chuàng)建7.11.…

文章目錄

    • 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+行。

代碼清單1AbstractApplicationContext.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);
代碼清單2AbstractApplicationContext.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中。

代碼清單3DefaultListableBeanFactory.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

代碼清單4AbstractBeanFactory.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 別名的解析處理
代碼清單5AbstractBeanFactory.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è)過
代碼清單6AbstractBeanFactory.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ì)象。

代碼清單7AbstractBeanFactory.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ì)象
代碼清單8AbstractBeanFactory.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
代碼清單9AbstractBeanFactory.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)建
代碼清單10AbstractBeanFactory.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ì)象
代碼清單11DefaultSingletonBeanRegistry.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

代碼清單12AbstractAutowireCapableBeanFactory.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
代碼清單13AbstractAutowireCapableBeanFactory.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ì)象
代碼清單14AbstractAutowireCapableBeanFactory.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ì)象的類型
代碼清單15AbstractAutowireCapableBeanFactory.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)建
代碼清單16AbstractAutowireCapableBeanFactory.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)化
代碼清單17AbstractAutowireCapableBeanFactory.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)作
代碼清單18AbstractAutowireCapableBeanFactory.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ì)象。

代碼清單19AbstractAutowireCapableBeanFactory.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)入屬性賦值前的注解信息收集。

代碼清單20AbstractAutowireCapableBeanFactory.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
代碼清單21InitDestroyAnnotationBeanPostProcessor.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
代碼清單22CommonAnnotationBeanPostProcessor.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
代碼清單23AutowiredAnnotationBeanPostProcessor.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ì)象引用。

代碼清單25AbstractAutowireCapableBeanFactory.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)行屬性賦值和依賴注入。

代碼清單26AbstractAutowireCapableBeanFactory.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
代碼清單27AbstractAutowireCapableBeanFactory.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
代碼清單28AbstractAutowireCapableBeanFactory.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。

代碼清單29AutowiredAnnotationBeanPostProcessor.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)屬性賦值
代碼清單30AbstractAutowireCapableBeanFactory.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方法。

代碼清單31AbstractAutowireCapableBeanFactory.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)
代碼清單32AbstractAutowireCapableBeanFactory.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)
代碼清單33AbstractAutowireCapableBeanFactory.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
代碼清單34InitDestroyAnnotationBeanPostProcessor.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
代碼清單35ApplicationContextAwareProcessor.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)
代碼清單36AbstractAutowireCapableBeanFactory.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)
代碼清單37AbstractAutowireCapableBeanFactory.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)。

代碼清單38AbstractAutowireCapableBeanFactory.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)建完成后,還有一段額外的邏輯。

代碼清單39DefaultListableBeanFactory.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源碼解讀與原理分析

http://www.risenshineclean.com/news/22459.html

相關(guān)文章:

  • 敦煌做網(wǎng)站的公司電話營(yíng)銷模式
  • 深圳網(wǎng)站建設(shè)哪家好附子seo
  • 新電商平臺(tái)seo整站優(yōu)化吧
  • wordpress 插件被墻免費(fèi)seo工具
  • 蘇州疫情最新政策seo外鏈資源
  • 淄博張店網(wǎng)站排名優(yōu)化怎么自己做一個(gè)網(wǎng)頁(yè)
  • 鷹潭做網(wǎng)站自己怎么做網(wǎng)站優(yōu)化
  • 南昌網(wǎng)站seo技術(shù)廠家如何做公司網(wǎng)站推廣
  • dedecms建手機(jī)網(wǎng)站游戲推廣是什么工作
  • 北京本地服務(wù)信息網(wǎng)西安seo站內(nèi)優(yōu)化
  • 永興縣網(wǎng)站建設(shè)公司哪家好湖人最新排名最新排名
  • 網(wǎng)站建設(shè)怎么記賬手機(jī)關(guān)鍵詞點(diǎn)擊排名軟件
  • 網(wǎng)站建設(shè)相關(guān)資料整理的重要性seo快排技術(shù)教程
  • nginx即代理又做網(wǎng)站競(jìng)價(jià)托管哪家效果好
  • 國(guó)內(nèi)大型php網(wǎng)站建設(shè)線上銷售如何找到精準(zhǔn)客戶
  • 順德外貿(mào)網(wǎng)站建設(shè)2024年新冠疫情最新消息今天
  • 網(wǎng)站收錄了怎么做排名百度關(guān)鍵詞是怎么排名靠前
  • 網(wǎng)站的外鏈怎么做免費(fèi)刷seo
  • b2c的電子信息網(wǎng)站系統(tǒng)清理優(yōu)化工具
  • 泉州制作網(wǎng)站開發(fā)搜索引擎環(huán)境優(yōu)化
  • 企業(yè)網(wǎng)站建設(shè)和實(shí)現(xiàn) 論文關(guān)鍵詞推廣怎么做
  • 西京一師一優(yōu)課建設(shè)網(wǎng)站深圳優(yōu)化排名公司
  • 福州免費(fèi)企業(yè)網(wǎng)站建站更先進(jìn)的seo服務(wù)
  • 網(wǎng)站建設(shè)主題與建設(shè)目標(biāo)最火網(wǎng)站排名
  • 濱城區(qū)住房和城鄉(xiāng)建設(shè)局網(wǎng)站seo優(yōu)化的優(yōu)點(diǎn)
  • 透視圖在什么網(wǎng)站上可以做企業(yè)網(wǎng)站設(shè)計(jì)欣賞
  • 北京個(gè)人網(wǎng)站建設(shè)多少錢西安市seo排名按天優(yōu)化
  • 交流網(wǎng)站建設(shè)心得體會(huì)百度指數(shù)查詢?nèi)肟?/a>
  • 交互動(dòng)效庫(kù) 網(wǎng)站晨陽(yáng)seo顧問
  • 網(wǎng)站 建設(shè)制作菜鳥教程建網(wǎng)站的流程