Spring 源碼筆記

也不指望有人看... 不過如果你看了的話, 希望你能告訴我你的感受, 以及可以改進(jìn)的地方!

Spring源碼分析

關(guān)鍵類介紹

ApplicationContext

萬能的 applicationContext, 但實(shí)際上各種能力都是依賴于其他的類, 比如 getBean 是 beanFactory 的, publishEvent 是事件廣播器的, 等等. 其本身是一個(gè)綜合體, 整合這些能力, 便于開發(fā)者調(diào)用和理解.

# 下面列一下相關(guān)的接口, 抽象類, 和具體類
ApplicationContext
    是一個(gè)只讀的 bean 容器
    可以加載解析配置文件(如xml)
    可以發(fā)布事件和注冊監(jiān)聽
    具有國際化消息處理能力
ConfigurableApplicationContext
    是一個(gè)具有可配置能力的 容器(可設(shè)置各個(gè)參數(shù), 如id, 父容器)
    具有容器生命周期概念, 如啟動(dòng),停止,關(guān)閉.
AbstractApplicationContext
    模板方法模式的抽象類, 定義了容器的模板(refresh方法), 但由具體的子類實(shí)現(xiàn)部分方法
    管理Bean和BeanFactory的PostProcessor
    管理事件的監(jiān)聽和處理
AbstractRefreshableApplicationContext
    為可重復(fù)刷新的容器提供基類
    加入了BeanFactory的管理(創(chuàng)建/關(guān)閉等)
AbstractRefreshableConfigApplicationContext
    加入了configLocation字段, 用于某些容器初始化BeanFactory和Bean
AbstractXmlApplicationContext
    定義了讀取xml配置文件來加載BeanFactory的代碼, 使得子類只需提供配置文件地址或Resource
ClassPathXmlApplicationContext
    繼承基類, 提供配置文件地址的構(gòu)造方法, 調(diào)用refresh加載BeanFactory
        

BeanFactory

1.核心中的核心, 加載和管理 beanDefinitions(Bean配置信息), 創(chuàng)建和管理 bean 對象實(shí)例, 注冊和管理 BeanPostProcessor(Bean擴(kuò)展)

# 下面列一下相關(guān)的接口, 抽象類, 和具體類
BeanFactory
  定義了 Bean 的基礎(chǔ)操作接口, 如 getBean, getType, isSingleton 等

SingletonBeanRegistry
  定義了單例對象的操作接口 (注冊/獲取/是否已存在) 

HierarchicalBeanFactory
  定義了父 BeanFactory 的相關(guān)操作接口(獲取)

ConfigurableBeanFactory
  定義了對 BeanFactory 做各種配置的操作接口, 包括 BeanPostProcessor, setParentBeanFactory, destroyBean, registerAlias, resolveAliases 等

DefaultSingletonBeanRegistry
  實(shí)現(xiàn)了 SingletonBeanRegistry 接口, 即實(shí)現(xiàn)了單例對象的緩存管理, 包括一級/二級/三級(二級三級只依賴循環(huán)用上的兩個(gè)緩存)
  
FactoryBeanRegistrySupport
  繼承了 DefaultSingletonBeanRegistry
    實(shí)現(xiàn)對使用 FactoryBean 存儲(chǔ)和獲取 bean 對象實(shí)例方式的支持
    
AbstractBeanFactory
  繼承了 FactoryBeanRegistrySupport
  實(shí)現(xiàn)了 BeanFactory/HierarchicalBeanFactory/ConfigurableBeanFactory 定義的接口
  實(shí)現(xiàn)了具體 getBean, 包括緩存管理等
  
AutowireCapableBeanFactory
  定義了根據(jù) class 類型獲取 BeanDefinition 信息以及 Bean 對象的接口

AbstractAutowireCapableBeanFactory
  繼承自 AbstractBeanFactory 
  實(shí)現(xiàn)了 AutowireCapableBeanFactory 中定義的方法(就是實(shí)現(xiàn)了根據(jù) class 獲取 bean 或 BeanDefinition)
  實(shí)現(xiàn)了 createBean, 也就是真正的實(shí)例化一個(gè)對象的過程, 包括實(shí)例化, 為需要賦值的字段注入相應(yīng)的值
  同時(shí)觸發(fā)了 BeanPostProcessor 的方法調(diào)用
  
BeanDefinitionRegistry
  定義了 BeanDefinition 的注冊/獲取/移除
  
ListableBeanFactory
    定義了 BeanDefinition 的可遍歷性
  
ConfigurableListableBeanFactory
  結(jié)合 ListableBeanFactory 和 ConfigurableBeanFactory 并補(bǔ)充完善了幾個(gè)相關(guān)接口 (如 getBeanNamesIterator 接口 )

DefaultListableBeanFactory
  繼承了 AbstractAutowireCapableBeanFactory
  實(shí)現(xiàn)了 BeanDefinitionRegistry/ConfigurableListableBeanFactory 的接口
 
# 總結(jié):
定義處:
BeanFactory(getBean)
SingletonBeanRegistry(addSingleton)
HierarchicalBeanFactory(getParentBeanFactory)
ConfigurableBeanFactory(addBeanPostProcessor)
AutowireCapableBeanFactory(autowireBean)
BeanDefinitionRegistry(registerBeanDefinition)
ListableBeanFactory(getBeanDefinitionNames)
ConfigurableListableBeanFactory(getBeanNamesIterator)

實(shí)現(xiàn)處:
DefaultSingletonBeanRegistry(registerSingleton)
FactoryBeanRegistrySupport(getObjectFromFactoryBean)
AbstractBeanFactory(doGetBean)
AbstractAutowireCapableBeanFactory(createBean)
DefaultListableBeanFactory(registerBeanDefinition)

容器初始化過程

1.setParent(): 處理父容器 
2.setConfigLocations(): 解析并設(shè)置xml配置文件路徑
3.refresh(): 創(chuàng)建 beanFactory 對象并初始化, 讀取 xml 配置文件得到 beanDefinitions, 接著處理兩種 PostProcessor, 然后添加國際化處理器和事件廣播器以及相應(yīng)的初始化和一些處理, 最后實(shí)例化單例的 bean 等等.

#外圈結(jié)束, 再看 refresh() 里面的每個(gè)方法
1.prepareRefresh(): 準(zhǔn)備工作, 一些字段值的設(shè)置和處理.
2.obtainFreshBeanFactory(): 創(chuàng)建一個(gè) beanFactory 對象并注冊到 applicationContext (即賦值到字段上), 然后解析 xml 配置文件(或注解配置)的信息, 解析得到 beanDefinitions 并注冊到容器中.
3.然后是一些對 beanFactory 對象的完善配置的代碼
4.掃描并執(zhí)行 BeanFactoryPostProcessor(其作用是為beanFactory對象添加?xùn)|西提供擴(kuò)展性), 其中我認(rèn)識的就只有 ConfigurationClassPostProcessor(這個(gè)類作用就是解析 @Configuration/@Component/@Import/@ImportSource/@ComponentScan等基礎(chǔ)注解).
5.掃描實(shí)現(xiàn)了 BeanPostProcessor 接口的 bean 并注冊到 beanFactory 中存起來, 等 createBean 創(chuàng)建對象時(shí)會(huì)在對應(yīng)的時(shí)機(jī)執(zhí)行一些對應(yīng)的方法(鉤子). 常見的各種 XxxAware 就是靠這個(gè)實(shí)現(xiàn)的咯.
6.接著, 初始化國際化資源處理器, 事件廣播器, 并注冊一些需要注冊的事件(也注冊容器內(nèi)實(shí)現(xiàn)對應(yīng)接口的 bean)
7.處理一些 beanFactory 的配置, 接著為所有單例且非懶加載的(不就是默認(rèn)策略嘛) bean 創(chuàng)建實(shí)例, 緩存起來.
8.廣播容器加載完成了的事件. 以及處理生命周期.

最后總結(jié)下, 先創(chuàng)建容器, 再將根據(jù)配置文件解析得到 BeanDefinition 注冊到容器中, 然后處理兩大擴(kuò)展(BeanFactoryPostProcessor/BeanPostProcessor), 接著是Spring的國際化, 以及相當(dāng)有用的事件廣播器, 最后實(shí)例化 bean. 整體感覺其實(shí)很簡單, 但其實(shí)有大量的工作交給了 BeanPostProcessor.

超長源碼分析過程

// 先隨便寫個(gè) main 方法, 如我寫的, 可測試依賴循環(huán)問題和事件監(jiān)聽:
// 包名: cn.gudqs7.spring.tests, 改動(dòng)則需同步修改xml哦
// 進(jìn)入對應(yīng)類代碼: 快捷鍵 Cmd+Option+鼠標(biāo)點(diǎn)擊 (或 Ctrl+Alt+鼠標(biāo)左鍵 ); 如果是接口松開 Option(或Alt)鍵

Test.java
public class Test {

    public static void main(String[] args) {
        ApplicationContext xmlContext = new ClassPathXmlApplicationContext("application-wq.xml");
        UserServiceImpl userService = xmlContext.getBean(UserServiceImpl.class);
        userService.sayHi();
    }

}


application-wq.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName">

    <bean name="userService" class="cn.gudqs7.spring.tests.UserServiceImpl">
        <property name="starter"><ref bean="serverStarter"/></property>
    </bean>
    <bean name="serverStarter" class="cn.gudqs7.spring.tests.ServerStarter">
        <property name="userService"><ref bean="userService"/></property>
    </bean>

</beans>

    
UserServiceImpl.java
@Service
public class UserServiceImpl {

    @Resource
    private ServerStarter starter;

    public void sayHi() {
        System.out.println(starter);
        System.out.println("Hello Spring!");
    }

    public void setStarter(ServerStarter starter) {
        this.starter = starter;
    }
}


ServerStarter.java
@Service
public class ServerStarter implements ApplicationListener<ContextRefreshedEvent> {

    @Inject
    private UserServiceImpl userService;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        String applicationName = event.getApplicationContext().getApplicationName();
        System.out.println(applicationName);
        System.out.println(userService);
        System.out.println("========== started by gudqs7 ==============");
        System.out.println("========== started by gudqs7 ==============");
        System.out.println("========== started by gudqs7 ==============");
    }

    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }
}

??????????????????????????????????????????????????????????????????

// 接下來, 進(jìn)入ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String) 方法中

// 其跳轉(zhuǎn)到了
  public ClassPathXmlApplicationContext(
            String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
            throws BeansException {

        // 為容器的 parent 字段賦值, 若 parent 不為空, 且有 ConfigurableEnvironment, 則合并數(shù)據(jù)(將父容器有的加到子容器中)
        // 即執(zhí)行了 org.springframework.context.support.AbstractApplicationContext.setParent()
        super(parent);

        // 為 configLocations 字段賦值(告知配置文件位置), 賦值前會(huì)根據(jù)環(huán)境變量解析(此時(shí)環(huán)境變量中只有系統(tǒng)環(huán)境變量: 如JAVA_HOME).
        setConfigLocations(configLocations);
        if (refresh) {
            // 注釋在下面
      refresh();
        }
    }
  
  

??????????????????????????????????????????????????????????????????

// 然后具體的看 refresh 方法
public void refresh() throws BeansException, IllegalStateException {
        // 1.設(shè)置容器初始的一些屬性(時(shí)間,狀態(tài)),初始化占位符數(shù)據(jù)源并校驗(yàn)所有 bean 所使用的占位符是否存在, 清空事件和監(jiān)聽
        // 2.清空重置舊的 beanFactory, 再創(chuàng)建新的 beanFactory 并通過解析 xml或注解 加載 beanDefinitions
        // 3.設(shè)置了一些 beanFactory 的屬性, 添加了幾個(gè)有用的 BeanPostProcessor, 還添加了幾個(gè) bean 到容器中(都是環(huán)境相關(guān)的 bean)
        // 4.子類對beanFactory 添加自己的特殊的 BeanPostProcessor (如servletContxt/servletConfig注入)
        // 5.掃描容器中實(shí)現(xiàn)了 BeanFactoryPostProcessor 接口的 bean 將其注冊到 beanFactory 中并執(zhí)行
        // 6.掃描容器中實(shí)現(xiàn)了 BeanPostProcessor 接口的 bean 將其注冊到 beanFactory 但不執(zhí)行(實(shí)例化 bean 對象那會(huì)有幾個(gè)執(zhí)行時(shí)機(jī))
        // 7.創(chuàng)建一個(gè)國際化資源解析器并注冊到 beanFactory; 創(chuàng)建一個(gè)事件廣播器并注冊到 beanFactory.
        // 8.調(diào)用子類的其他刷新時(shí)需要做的事情(模板方法)
        // 9.掃描容器中實(shí)現(xiàn)了 ApplicationListener 接口的 bean, 將其預(yù)存到廣播器中但不執(zhí)行
        //10.完成 beanFactory 的一些配置(包括終結(jié)一些東西, 如 setTempClassLoader(null) ); 將單例的 bean 創(chuàng)建出來放入容器中(未設(shè)置lazy-init=true)的 bean
        //11.廣播 ContextRefreshedEvent 事件, 初始化LifeCycleProcessor及調(diào)用其 onRefresh 方法.

        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            // 設(shè)置容器初始的一些屬性(時(shí)間,狀態(tài)),初始化占位符數(shù)據(jù)源并校驗(yàn)所有 bean 所使用的占位符是否存在, 清空事件和監(jiān)聽
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            // 清空重置舊的 beanFactory, 再創(chuàng)建新的 beanFactory 并解析 xml或注解 加載 beanDefinitions
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            // 設(shè)置了一些 beanFactory 的屬性, 添加了幾個(gè)有用的 BeanPostProcessor, 還添加了幾個(gè) bean 到容器中(都是環(huán)境相關(guān)的 bean)
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                // 子類對beanFactory 添加自己的特殊的 BeanPostProcessor (如servletContxt/servletConfig注入)
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                // 掃描容器中實(shí)現(xiàn)了 BeanFactoryPostProcessor 接口的 bean 將其注冊到 beanFactory 中并執(zhí)行
                //   掃描6次, 2(BeanDefinitionRegistry/BeanFactory) x 3(優(yōu)先級:高/中/其他)
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                // 掃描容器中實(shí)現(xiàn)了 BeanPostProcessor 接口的 bean 將其注冊到 beanFactory 但不執(zhí)行; 掃描6次: 2(MergedBeanDefinitionPostProcessor/其他) x 3(優(yōu)先級: 高/中/其他)
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                // 創(chuàng)建一個(gè)國際化資源解析器并注冊到 beanFactory.
                initMessageSource();

                // Initialize event multicaster for this context.
                // 創(chuàng)建一個(gè)事件廣播器并注冊到 beanFactory.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                // 調(diào)用子類的其他刷新時(shí)需要做的事情(模板方法)
                onRefresh();

                // Check for listener beans and register them.
                // 將可能存在的 applicationListeners 注冊到事件廣播器中(新建時(shí)是不存在的),
                // 然后掃描容器中實(shí)現(xiàn)了 ApplicationListener 接口的 bean, 將其預(yù)存到廣播器中但不執(zhí)行
                // 將之前 publishEvent() 想廣播的事件廣播出去, 然后字段 earlyApplicationEvents 賦值為空(代表之后可立即廣播)
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                // 完成 beanFactory 的一些配置(包括終結(jié)一些東西, 如 setTempClassLoader(null) )
                // 注冊默認(rèn)的表達(dá)式解析器(若無相應(yīng)的bean存在)
                // 掃描容器中實(shí)現(xiàn)了 LoadTimeWeaverAware 接口的 bean, 并觸發(fā)(getBean)之前注冊過的 BeanPostProcessor
                // 將單例的 bean 創(chuàng)建出來放入容器中(未設(shè)置lazy-init=true)的 bean
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                // 廣播 ContextRefreshedEvent 事件, 初始化LifeCycleProcessor及調(diào)用其 onRefresh 方法.
                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.
                // 變更狀態(tài)
                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...
                // 清空公共工具產(chǎn)生的緩存(內(nèi)存松一口氣).
                resetCommonCaches();
            }
        }
    }

我錯(cuò)了, 代碼都放上去不如給個(gè)GitHub地址, 接下來省略代碼吧, 只放注釋??????????????????????????????

// 挨個(gè)看里面的方法
org.springframework.context.support.AbstractApplicationContext#prepareRefresh
    // 1.設(shè)置容器初始的一些屬性, 如啟動(dòng)時(shí)間, 當(dāng)前狀態(tài)
        // 2.打印開始日志
        // 3.初始化占位符數(shù)據(jù)源
        // 4.校驗(yàn)所有 bean 所使用的占位符是否存在
        // 5.清空事件和監(jiān)聽
        // Switch to active.
  
org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory
    // 1.存在舊的則先摧毀 bean 對象實(shí)例及緩存數(shù)據(jù), 再將舊的置為 null
        // 2.創(chuàng)建一個(gè)新的 beanFactory 對象, 再設(shè)置 id及一些配置
        // 3.掃描并加載 beanDefinations
        // 4.設(shè)置這個(gè)新的 beanFactory 對象為 applicationContext 的 beanFactory 字段值.
  
org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory
    // 1.設(shè)置 beanFactory 的類加載器
        // 2.設(shè)置 beanFactory 的表達(dá)式解析器
        // 3.1:注冊一個(gè) BeanPostProcessor 用于將實(shí)現(xiàn)了ApplicationContext能力相關(guān)的Aware接口的 bean, 觸發(fā)賦值setter 注入 applicationContext 對象
        // 3.2:設(shè)置 beanFactory 處理 bean 時(shí)要忽略的接口(主要是setter注入時(shí)忽視一些也是setter的方法, 因?yàn)檫@些方法會(huì)由 PostProcessor 來觸發(fā))
        // 4.注冊一些特殊的 bean(注入這些bean時(shí)會(huì)注入 this 對象: 多功能工具人 ApplicationContext, 可見其和普通 bean 的注冊方式不一樣)
        // 5.注冊一個(gè) BeanPostProcessor 用于檢測加載的 bean 是否實(shí)現(xiàn)了 ApplicationListener 接口, 若是, 則注冊到事件廣播器中(不是,是暫存在applicationListeners字段中, 等事件廣播器創(chuàng)建后才注冊)
        // 6.注冊一個(gè) BeanPostProcessor 用于觸發(fā)實(shí)現(xiàn)了 LoadTimeWeaverAware 接口的 bean 的 setLoadTimeWeaver() 社會(huì) LTW 實(shí)例.
        // 7.注冊幾個(gè)環(huán)境相關(guān) bean 到容器中(Spring的環(huán)境對象, 以及系統(tǒng)環(huán)境變量和系統(tǒng)配置文件)

org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)
    // 1.若 beanFactory 實(shí)現(xiàn)了 BeanDefinitionRegistry 接口(new AnnotationConfigApplicationContext 就實(shí)現(xiàn)了)
        //    則掃描所有實(shí)現(xiàn)了 BeanDefinitionRegistryPostProcessor 接口的 bean, 根據(jù)優(yōu)先級分三類(高/中/其他)依次執(zhí)行
        // 2.然后掃描所有實(shí)現(xiàn)了 BeanFactoryPostProcessor 接口的 bean, 依舊是根據(jù)優(yōu)先級分三類依次執(zhí)行.
        // 3.每次執(zhí)行前都會(huì)根據(jù) Order 信息排序, 再遍歷執(zhí)行
  
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
    // 1.掃描6次: 2(MergedBeanDefinitionPostProcessor/其他) x 3(優(yōu)先級: 高/中/其他)
        //    將其加入到 beanFactory 的 beanPostProcessors 集合中
        // 2.再次加入 ApplicationListenerDetector (用于處理實(shí)現(xiàn) ApplicationListener 的 bean 注冊到事件廣播器), 主要是使其在鏈末尾, 可以最后執(zhí)行.

org.springframework.context.support.AbstractApplicationContext#registerListeners
    // 1.將可能存在的 applicationListeners 注冊到事件廣播器中(新建時(shí)是不存在的)
        // 2.掃描容器中實(shí)現(xiàn)了 ApplicationListener 接口的 bean, 將其預(yù)存到廣播器中但不執(zhí)行
        // 3.將之前 publishEvent() 想廣播的事件廣播出去, 然后字段 earlyApplicationEvents 賦值為空
        //    (因?yàn)?publishEvent() 中根據(jù)是否為空判斷立刻執(zhí)行或先存著) (另這也解釋了 prepareRefresh() 中為何要賦值一個(gè)空集合)

  
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
    // 1.完成 beanFactory 的一些配置
        // 2.注冊默認(rèn)的表達(dá)式解析器(若無相應(yīng)的bean存在)
        // 3.掃描容器中實(shí)現(xiàn)了 LoadTimeWeaverAware 接口的 bean, 并觸發(fā)(getBean)之前注冊過的 BeanPostProcessor
        // 4.將單例的 bean 創(chuàng)建出來放入容器中(未設(shè)置lazy-init=true)的 bean

org.springframework.context.support.AbstractApplicationContext#finishRefresh
    // 1.清空資源緩存
        // 2.創(chuàng)建一個(gè)生命周期管理器(start, refresh, stop等)并注冊到 beanFactory
        // 3.觸發(fā)生命周期管理器的 onRefresh()
        // 4.廣播容器刷新完成的事件
        // 5.為 Spring Tool Suite 提供某些便捷(沒用過, 不知道...)

可算復(fù)制完了, 如果你有幸直接跳讀到這里, 那么送上地址 : 注意分支吧

另外上面方法前帶個(gè) # 的, 復(fù)制到 IDEA 雙擊 Shift 然后粘貼, 選擇 Symbols 搜索更準(zhǔn)確呢!

獲取容器對象過程

# 從getBean(Class type) 中進(jìn)入
1.檢查 applicationContext 和 beanFactory 的狀態(tài), 若有異常則給出準(zhǔn)確的錯(cuò)誤.
2.掃描容器中所有此 type 的 beanName, 遍歷判斷每個(gè) beanName 是否可用
   可用則判斷可用的個(gè)數(shù)是否剛好是一個(gè), 是則直接調(diào)用 getBean() 返回對象實(shí)例
   若可用的個(gè)數(shù)超過一個(gè), 則根據(jù) beanDefinition 的 isPrimary 和對比配置的優(yōu)先級是否為有最高的再返回最高的
   若都不行, 則報(bào)錯(cuò).
3.接著看 getBean, 先試著從單例的緩存中獲取, 若存在則返回.
4.若緩存中不存在, 則判斷父容器是否存, 若存在則從父容器獲取
   若父容器不存在, 則自己新建, 先標(biāo)記 beanName 到 alreadyCreated 中(表示已經(jīng)創(chuàng)建了防止重復(fù)創(chuàng)建) 再開始創(chuàng)建一個(gè) bean.
5.創(chuàng)建一個(gè)新的 bean 實(shí)例, 先處理 beanDefinition 的 dependsOn 屬性(即若存在則先調(diào)用 getBean 獲取依賴的 bean)
6.若 beanDefinition 的設(shè)置是單例, 則通過閉包對創(chuàng)建對象前后進(jìn)行一些異常處理和緩存處理(主要是徹底創(chuàng)建完后加入到單例一級緩存, 移除二級和三級緩存[循環(huán)依賴相關(guān)的兩個(gè)緩存]).
7.通過反射根據(jù) beanClass 創(chuàng)建一個(gè)對象實(shí)例, 然后將其添加到 singletonFactories 中(解決依賴循環(huán)問題)
8.調(diào)用 populateBean() 為對象的字段(屬性)注入它所需要的值(可能是@Resource, @Value等); (此時(shí)可能會(huì)遇到依賴循環(huán)問題, 但解決這個(gè)問題的緩存在此之前就添加了, 所以不怕)
9.最后調(diào)用 initializeBean() 完成 bean 的初始化(調(diào)用 bean 的一些方法, 如 afterPropertiesSet), 返回對象實(shí)例.

總結(jié): 先根據(jù) type 找到 beanName, 找到后根據(jù) beanName 創(chuàng)建對象; 創(chuàng)建對象前先檢查緩存(單例), 再考慮父容器, 最后才是自己創(chuàng)建, 自己創(chuàng)建會(huì)先創(chuàng)建 dependsOn 的 bean 對象, 然后才通過反射實(shí)例化出一個(gè)對象實(shí)例(這里反射用到的class和構(gòu)造方法, 通過實(shí)現(xiàn) SmartInstantiationAwareBeanPostProcessor接口都可進(jìn)行干預(yù)), 實(shí)例化后存到二級緩存, 再為字段賦值(注入); 最后調(diào)用 bean 的 init 相關(guān)的接口(如afterPropertiesSet), 就可以返回這個(gè)對象實(shí)例了.

超長源碼分析過程

// 從這個(gè)方法進(jìn)入
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
  // 判斷容器的狀態(tài), 確保 beanFactory 可用.(主要是若不可用, 提示的錯(cuò)誤信息會(huì)比getBeanFacgtory()中更準(zhǔn)確)
  // 使用 beanFactory 的 getBean 方法獲取對象并返回.
  assertBeanFactoryActive();
  return getBeanFactory().getBean(requiredType);
}

// 然后其他所有涉及的核心方法的注釋
org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveBean
    // 調(diào)用 resolveNamedBean, 如存在 bean 則直接返回. (核心)
        // 若不存在則從父容器中尋找, 父容器實(shí)現(xiàn)了 DefaultListableBeanFactory 則調(diào)與同子容器相同的方法
        // 若沒實(shí)現(xiàn)則 通過 getBeanProvider 獲取.
  
org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveNamedBean(org.springframework.core.ResolvableType, java.lang.Object[], boolean)
    // 1.調(diào)用 getBeanNamesForType 獲取所有與 type 相匹配的 beanName 集合.
        // 2.遍歷判斷每個(gè) beanName 是否可用
        // 3.若可用的 beanName 只有一個(gè), 則調(diào)用 getBean(beanName) 獲取對象實(shí)例并返回
        //   若可用數(shù)超過一個(gè), 則試著根據(jù)是否主要以及高優(yōu)先級來確定一個(gè) beanName 實(shí)例, 若能確定則返回, 不能則報(bào)錯(cuò).

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
    // 1.獲取完整的 beanName
        // 2.調(diào)用 getSingleton1() 檢查是否存在緩存, 這層檢查可防止依賴循環(huán).
        //     若存在, 則通過 getObjectForBeanInstance() 判斷緩存的是 bean 還是 FactoryBean 并返回相應(yīng)的對象實(shí)例.
        // 3.若不存在, 先試著從父容器獲取(子容器不存在這個(gè) beanDefinition 且父容器不為空)
        //     沒有父容器則 調(diào)用 markBeanAsCreated() 標(biāo)記這個(gè) bean已經(jīng)創(chuàng)建了 (先標(biāo)記, 再創(chuàng)建)
        //     獲取 beanDefinition, 判斷其 dependsOn 屬性是否存在, 存在則 先獲取依賴的 bean
        //     調(diào)用 getSingleton2() 處理單例緩存
        // 4.而 getSingleton2() 中的閉包中 執(zhí)行的 createBean() 方法中則才是創(chuàng)建實(shí)例并調(diào)用 BeanPostProcessor

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
    // 1.判斷是否存在于 singletonObjects 中
        // 2.若不存在則判斷 bean 是否處于創(chuàng)建中(未創(chuàng)建完成, 如循環(huán)依賴時(shí))
        // 3.若處于創(chuàng)建中, 則同步后判斷是否存在于 earlySingletonObjects (也就是 singletonFactories 移除后存入的地方)
        //      (因?yàn)镕actoryBean占用空間大, 獲取對象麻煩且速度更慢, 這是為了防止如果循環(huán)依賴鏈條很長 多次獲取浪費(fèi)CPU的問題)
        // 4.不存于 earlySingletonObjects 則代表第一次(也只會(huì)有一次)取 singletonFactories
        //    取出后調(diào)用 getObject() 并將其存入到 earlySingletonObjects, 然后從 singletonFactories 中移除. 以后就少走幾行代碼了.
  
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
    // 1.先確保是第一次創(chuàng)建單例對象, 防止重復(fù)創(chuàng)建
        // 2.進(jìn)行一些異常處理
        // 3.調(diào)用 singletonFactory.getObject() 創(chuàng)建對象
        // 4.創(chuàng)建對象結(jié)束添加單例緩存和清空 singletonFactories / earlySingletonObjects 緩存.
  
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
    // 1.調(diào)用 resolveBeanClass 解析得到真正的 bean class, 若解析不為空且處于某些情況下, 則復(fù)制一份 beanDefinition 并設(shè)置 beanClass 為解析所得
        // 2.執(zhí)行 BeanPostProcessor 的 postProcessorsBeforeInstantiation() 方法
        // 3.調(diào)用 doCreateBean() 創(chuàng)建對象 并返回

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
    // 1.調(diào)用 createBeanInstance() 獲得一個(gè) 對象實(shí)例的 包裝類
        // 2.同步鎖下執(zhí)行 BeanFactoryPostProcessor 的 postProcessMergedBeanDefinition().
        // 3.添加 singletonFactories 緩存, 移除 earlySingletonObjects; 解決循環(huán)依賴問題.
        // 4.調(diào)用 populateBean() 檢查字段是否需要注入對象實(shí)例, 是則獲取對應(yīng)的 bean 注入. (可能引起循環(huán)依賴)
        // 5.調(diào)用 initializeBean() 執(zhí)行對象的一些 Aware 和 init 方法和 BeanPostProcessor 的 postProcessBeforeInitialization.
        // 6.最后返回對象實(shí)例.


各種實(shí)現(xiàn)的原理

1.為何我寫的 class 實(shí)現(xiàn)一些接口(如ApplicationContextAware)后并放入容器中, 就可以獲取到一些對象(如applicationContext)?
2.為何我寫的 class 實(shí)現(xiàn) ApplicationListener<XxxEvent> 后并放入容器中, 就能監(jiān)聽我想知道的事件?
3.為何Spring中遇到各種順序問題, 只需要實(shí)現(xiàn) Ordered 接口(或加上@Order注解)就能使其有序?
4.Spring是如何解決循環(huán)依賴的(指用字段注入而非構(gòu)造方法)?
5.Spring可以用注解替換XML配置文件了, 是如何實(shí)現(xiàn)的呢(常用注解的實(shí)現(xiàn)原理)?
6.Spring AOP是如何實(shí)現(xiàn)的(指@Aspect)?
7.Spring 事務(wù)是如何實(shí)現(xiàn)的(指@Transaction)?

為何我寫的 class 實(shí)現(xiàn)一些接口(如ApplicationContextAware)后并放入容器中, 就可以獲取到一些對象(如applicationContext)?

1) 首先 AbstractApplicationContext#prepareBeanFactory 會(huì)添加一個(gè)ApplicationContextAwareProcessor
2) 這個(gè) beanPostProcessor 負(fù)責(zé)在bean初始化之前注入context對象.
3) 這個(gè) beanPostProcessor 的執(zhí)行時(shí)機(jī)是在 doCreateBean 中的 postProcessBeforeInitialization()

為何我寫的 class 實(shí)現(xiàn) ApplicationListener<XxxEvent> 后并放入容器中, 就能監(jiān)聽我想知道的事件?

1) 在 AbstractApplicationContext#registerListeners() 中掃描容器內(nèi)所有相關(guān)實(shí)現(xiàn)類加入到事件監(jiān)聽者集合中
2) 然后在publishEvent時(shí),遍歷事件監(jiān)聽者集合調(diào)用bean的方法即可。觀察者模式!
3) 另外也用了BeanPostProcessor去實(shí)現(xiàn), 叫 ApplicationListenerDetector, 加入時(shí)機(jī)同1, 執(zhí)行時(shí)機(jī)同1.
4) 至于為何使用2種機(jī)制, 應(yīng)該是因?yàn)?registerListeners() 時(shí), 掃描只是當(dāng)前的, 后續(xù)可能容器內(nèi)的 bean 還會(huì)增加(我也猜不到啥形式增加, 反正簡單寫個(gè)類肯定不會(huì)), 所以還是需要 ApplicationListenerDetector 在這個(gè) Bean 初始化時(shí)加入到監(jiān)聽者中去.

為何Spring中遇到各種順序問題, 只需要實(shí)現(xiàn) Ordered 接口(或加上@Order注解)就能使其有序?

因?yàn)?Spring 預(yù)先在執(zhí)行這些東西之前, 進(jìn)行一個(gè)排序動(dòng)作, 然后才遍歷執(zhí)行. 包括AOP, BeanFactoryPostProcessor, BeanPostProcessor .

1) 比如說 BeanPostProcesser, 容器掃描后, 會(huì)像對bean集合排序, 再遍歷執(zhí)行.
2) 詳細(xì)過程見 PostProcessorRegistrationDelegate#sortPostProcessors()

Spring是如何解決循環(huán)依賴的(指用字段注入而非構(gòu)造方法)?

1) 首先, 假定有兩個(gè)單例 bean A 和 B, A 持有 B, B 持有A, 構(gòu)成循環(huán)
2) 此時(shí)程序調(diào)用getBean獲取A,則在 doCreateBean 中 創(chuàng)建后將 bean 緩存到 singletonFactories 中
3) 然后設(shè)置屬性B, 解析屬性, 需要獲取B對象
4) 獲取B, 則執(zhí)行doCreateBean 后執(zhí)行解析屬性, 需要獲取 A對象 (又一次)
5) 獲取A, 進(jìn)入 doGetBean 中的 getSingleton, 此時(shí)判斷 singletonFactories 中有A, 則可以直接取出A
6) 獲得A后, 即可完成B的屬性賦值, 然后會(huì)完成B的創(chuàng)建.
7) B創(chuàng)建完后, A就能獲得B, 則A也完成了屬性賦值, 最后完成創(chuàng)建A.
8) 到此, 返回即可.

> 總結(jié): 首次獲取A, 創(chuàng)建A對象后緩存一個(gè)存儲(chǔ)A對象的 ObjectFactory 實(shí)例, 再解析屬性時(shí)觸發(fā) getBean(B), 同理也會(huì)做緩存, 然后也解析屬性, 觸發(fā)getBean(A), 第二次獲取A, 進(jìn)入另一個(gè)邏輯, 返回 ObjectFactory 實(shí)例中存儲(chǔ)的對象A, 即可完成getBean(A), 然后完成getBean(B), 再完成外層的getBean(A).  
  
TIPS:
步驟4中, 會(huì)先判斷 earlySingletonObjects, 不存在才判斷 singletonFactories, 而從 singletonFactories 中取得對象后, 則會(huì)將其從 singletonFactories 移除并加入 earlySingletonObjects

這是因?yàn)?singletonFactories 緩存的 FactoryBean, 若反復(fù)調(diào)用 getObject(), 則每次獲取都會(huì)調(diào)用 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getEarlyBeanReference 方法, 而此方法會(huì)執(zhí)行 SmartInstantiationAwareBeanPostProcessor 的 getEarlyBeanReference(), 這會(huì)導(dǎo)致 BeanPostProcessor 重復(fù)執(zhí)行, 顯然是不行的.

Spring可以用注解替換XML配置文件了, 是如何實(shí)現(xiàn)的呢(常用注解的實(shí)現(xiàn)原理)?

1) 首先是指定包名或指定類名
    如指定包名則 scan 時(shí)會(huì)執(zhí)行, 如指定類名則在構(gòu)造方法初始化 reader 時(shí)執(zhí)行
2) 無論哪種, 最終都會(huì)走一段代碼 AnnotationConfigUtils#registerAnnotationConfigProcessors()
3) 這段代碼會(huì)添加一些 BeanFactoryPostProcessor
    如 ConfigurationClassPostProcessor 負(fù)責(zé)解析 @Configuration/@Import/@Bean 等注解
        然后由 ConfigurationClassBeanDefinitionReader 負(fù)責(zé)將信息轉(zhuǎn)換成BeanDefinition再注冊到容器。
    如 AutowiredAnnotationBeanPostProcessor 負(fù)責(zé)解析 @Autowired/@Value 注解
    如 CommonAnnotationBeanPostProcessor 負(fù)責(zé)解析 @Resource 注解
    解析放在 postProcessProperties() 方法中, 先掃描bean的字段和方法, 然后一一調(diào)用方法和為字段注入值
4) 之后, 他會(huì)將掃描的類放到 beanDefinitions 中(或指定的類注冊進(jìn)去)
5) BeanFactory加載完畢后, 回到AbstractApplicationContext的refresh邏輯
    如會(huì)執(zhí)行 postProcessBeanFactory(), 調(diào)用前面加入的ConfigurationClassPostProcessor
    然后會(huì)添加更多的類到容器中.
    
注意事項(xiàng):
    @Configuration 和 @Component的區(qū)別?
    觀察發(fā)現(xiàn),即使使用@Component 其下帶 @Bean 的方法依然可以注入到容器中。所以似乎兩者沒有區(qū)別?
    仔細(xì)查看源碼和資料后,發(fā)現(xiàn) postProcessBeanFactory() 方法在 processConfigBeanDefinitions() 后還會(huì)調(diào)用 enhanceConfigurationClasses()
    而在這個(gè)方法中, 對前面解析了class 是 CONFIGURATION_CLASS_FULL (即代表@Configuration)的類
    會(huì)生成一個(gè) cglib 的代理, 這樣獲取@Bean注解的方法的bean時(shí),不會(huì)每次調(diào)用方法new 一個(gè), 而是有緩存.

總結(jié): 就是利用 BeanFactoryPostProcessor 可獲取 BeanDefinitionRegistry 對象, 然后掃描容器內(nèi)帶有注解的 bean, 解析這些注解得到一些 BeanDefinition, 再通過獲得的 BeanDefinitionRegistry對象注冊到 BeanFactory 中.

Spring AOP是如何實(shí)現(xiàn)的(指@Aspect)?

1) 使用 @EnableAspectJAutoProxy
2) @EnableAspectJAutoProxy 中使用了 @Import(AspectJAutoProxyRegistrar.class)
3) ConfigurationClassPostProcessor 會(huì)解析@Import, 進(jìn)入 registerBeanDefinitions() 中
4) registerBeanDefinitions() 中添加了 AnnotationAwareAspectJAutoProxyCreator 到容器中
5) AnnotationAwareAspectJAutoProxyCreator 本質(zhì)上時(shí)一個(gè) BeanPostProcessor
6) 因此在 createBean 時(shí), 會(huì)被自動(dòng)調(diào)用. 其中 postProcessAfterInitialization() 負(fù)責(zé)創(chuàng)建代理對象
7) 而 getAdvicesAndAdvisorsForBean() 則負(fù)責(zé)查找對應(yīng)的增強(qiáng). 然后會(huì)調(diào)用子類的findCandidateAdvisors
8) 如 AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors() 負(fù)責(zé)注解編寫增強(qiáng)@Before/@After等
9) 簡單說下邏輯, 就是查找容器所有類, 判斷這個(gè)類有沒有 @Aspect 注解, 然后先找出所有Pointcut
    再遍歷所有方法, 找出方法上帶有@Before等注解且有關(guān)聯(lián)的Pointcut的方法,
    然后使用這個(gè)方法和關(guān)聯(lián)的Pointcut 來new 一個(gè)Advisor, 加入到Advisor集合中, 遍歷結(jié)束后返回即可.
10) 查找到所有的增強(qiáng)后, 再比較Pointcut表達(dá)式是否匹配當(dāng)前的bean, 如可以則加入.
11) 根據(jù)找到的Advisor集合, 創(chuàng)建一個(gè)帶配置(advisor集合等)的代理對象, 代理對象執(zhí)行方法前
12) 會(huì)先根據(jù)配置中的advisor集合生成一個(gè)執(zhí)行鏈, 然后在攔截代理方法處調(diào)用. 執(zhí)行鏈會(huì)負(fù)責(zé)執(zhí)行通知.
13) 不同的通知由不同的適配器執(zhí)行.

總結(jié)就是通過 @EnableAspectJAutoProxy 的@Import, 使得程序最終會(huì)執(zhí)行 AnnotationAwareAspectJAutoProxyCreator 的 postProcessAfterInitialization(對象初始化后調(diào)用) 方法, 這個(gè)方法在 BeanFactory創(chuàng)建完對象后觸發(fā), 此時(shí)便可通過 CGlib 等動(dòng)態(tài)代理技術(shù)為 創(chuàng)建的 bean 對象創(chuàng)建一個(gè)代理對象, 然后這個(gè)代理對象會(huì)根據(jù) Pointcut 找到關(guān)聯(lián)的 Advisor, 并在合適的時(shí)機(jī)執(zhí)行對應(yīng)的 Advisor, 如 @Before產(chǎn)生的Advisor 會(huì)在執(zhí)行了 bean 對象的指定方法(看Pointcut配置)后執(zhí)行.

Spring 事務(wù)是如何實(shí)現(xiàn)的(指@Transaction)?

0) 事務(wù)是由AOP實(shí)現(xiàn)的, 所以需要找到對應(yīng)的Pointcut 和 Advisor
1) 打開了 @EnableTransactionManagement 注解
2) 然后@Import 了 TransactionManagementConfigurationSelector
3) 之后導(dǎo)入了 ProxyTransactionManagementConfiguration 到容器中
4) ProxyTransactionManagementConfiguration 帶有 @Configuration
5) @Bean 注入了一個(gè)通用的Advisor: BeanFactoryTransactionAttributeSourceAdvisor
6) 這個(gè)Advisor的 Pointcut 是由 TransactionAttributeSourcePointcut 實(shí)現(xiàn)的
    實(shí)現(xiàn)邏輯是 TransactionAttributeSourcePointcut 的 matches()
    這個(gè)方法調(diào)用了 getTransactionAttributeSource() 獲取 AnnotationTransactionAttributeSource
    然后通過 getTransactionAttribute() 調(diào)用了 findTransactionAttribute()
    最終使用SpringTransactionAnnotationParser 類判斷方法是否有@Transactional注解
    并解析注解信息然后返回. 另外這個(gè)方法還可以獲取@Transactional注解的信息, 而這里只用于判斷是否需要攔截這個(gè)方法.
7) TransactionInterceptor 是一個(gè)Advisor
    也可以通過AnnotationTransactionAttributeSource獲取@Transactional注解上的信息
    然后在invoke中, 攔截方法, 打開事務(wù), 在執(zhí)行完方法后, 提交事務(wù), 報(bào)錯(cuò)時(shí)回滾事務(wù)
    這個(gè) Advisor 不同于傳統(tǒng)的前置/后置, 而是更具體的 MethodInterceptor(動(dòng)態(tài)代理直接相關(guān)).

總結(jié): 就是基于AOP實(shí)現(xiàn)的, 只需找到對應(yīng)的 Pointcut 和 Advisor 即可. Pointcut 就是根據(jù) @Transaction 注解判斷方法是否需要代理, 這個(gè)很簡單; 比較有意思的是 Advisor 不是我們寫AOP那種 @Before,@Around之類的, 而是更接近動(dòng)態(tài)代理原始的語法的 MethodInterceptor 即 TransactionInterceptor.

BeanFactoryPostProcessor 相關(guān)類分析

BeanFactoryPostProcessor 生效原理

生效原理就是, ApplicationContext 的 refresh 方法中會(huì)掃描出容器中實(shí)現(xiàn)了 BeanFactoryPostProcessor 接口的 bean, 將其排序后執(zhí)行相應(yīng)的接口, 這樣我們寫的類實(shí)現(xiàn)的相應(yīng)的接口的方法就被執(zhí)行了.

常用的 BeanFactoryPostProcessor
# ConfigurationClassPostProcessor
這個(gè)類作用就是解析 @Configuration/@Component/@Import/@ImportSource/@ComponentScan 等基礎(chǔ)注解. 是注解開發(fā)的基石, 更是 Spring Boot 的基石.

BeanPostProcessor 相關(guān)類分析

BeanPostProcessor 生效原理

在 refresh() 中會(huì)掃描容器中所有 實(shí)現(xiàn)了 BeanPostProcessor 接口的類, 添加到 BeanFactory 的 beanPostProcessors 字段中(是個(gè)List[CopyOnWriteArrayList自定義版, 自定義加入了清空緩存的邏輯]), 然后在 BeanFactory 創(chuàng)建對象時(shí) createBean() 在適當(dāng)?shù)臅r(shí)機(jī)調(diào)用對應(yīng)的方法.

有哪幾種 BeanPostProcessor (默認(rèn)的+擴(kuò)展)
1.InstantiationAwareBeanPostProcessor
    postProcessAfterInstantiation: 對象實(shí)例化后調(diào)用
    postProcessBeforeInstantiation: 對象實(shí)例化前調(diào)用
    postProcessProperties: 設(shè)置屬性值前
    postProcessPropertyValues: 設(shè)置屬性值前, 若上個(gè)方法不處理(返回null)才會(huì)觸發(fā)

2.SmartInstantiationAwareBeanPostProcessor
  predictBeanType: 獲取一個(gè) bean 的 class 類型前調(diào)用
  getEarlyBeanReference: 獲取一個(gè)二級緩存對象(singletonFactories的getObject)時(shí)調(diào)用
  determineCandidateConstructors: 決定一個(gè) bean 實(shí)例化的構(gòu)造參數(shù)是什么時(shí)調(diào)用
    
3.DestructionAwareBeanPostProcessor
    postProcessBeforeDestruction: 對象銷毀前調(diào)用
    requiresDestruction: 判斷這個(gè)類針對某個(gè) bean 是否執(zhí)行 postProcessBeforeDestruction()
    
4.MergedBeanDefinitionPostProcessor
  postProcessMergedBeanDefinition: 在創(chuàng)建對象前調(diào)用, 可對 BeanDefinition 做修改
  resetBeanDefinition: 在重置 BeanDefinition 時(shí)調(diào)用, 用于清空 PostProcessor 對應(yīng)的緩存
    
5.BeanPostProcessor(基礎(chǔ))
  postProcessBeforeInitialization: 創(chuàng)建對象后(也設(shè)置好了字段), 在調(diào)用 init 之前調(diào)用
  postProcessAfterInitialization: 在創(chuàng)建對象時(shí), 調(diào)用了 init 之后調(diào)用
  
總結(jié): 
0.對 BeanDefinition 做干預(yù)
1.對象實(shí)例化過程中(對class/構(gòu)造參數(shù)進(jìn)行干預(yù))
2.對象實(shí)例化前后
3.對象設(shè)置屬性前, 對屬性做干預(yù)
4.對象初始化(init)前后
5.對象銷毀前

調(diào)用時(shí)機(jī)

    // 1.1: InstantiationAwareBeanPostProcessor 的 postProcessAfterInstantiation()
        //   在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean 第一段
        // 1.2: InstantiationAwareBeanPostProcessor 的 postProcessProperties()
        //   在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean 第二段
        // 1.3: InstantiationAwareBeanPostProcessor 的 postProcessPropertyValues
        //   在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean 第三段
        // 1.4: InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation()
        //   在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation 中

        // 2.1: SmartInstantiationAwareBeanPostProcessor 的 predictBeanType()
        //   在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType 中
        // 2.2: SmartInstantiationAwareBeanPostProcessor 的 getEarlyBeanReference()
        //   在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getEarlyBeanReference 中
        // 2.3: SmartInstantiationAwareBeanPostProcessor 的 determineCandidateConstructors()
        //   在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineConstructorsFromBeanPostProcessors 中

        // 3.1: MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition()
        //   在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors 中
        // 3.2: MergedBeanDefinitionPostProcessor 的 resetBeanDefinition()
        //   在 org.springframework.beans.factory.support.DefaultListableBeanFactory.resetBeanDefinition 中

        // 4.1: DestructionAwareBeanPostProcessor 的 postProcessBeforeDestruction()
        //   在 org.springframework.beans.factory.support.DisposableBeanAdapter.destroy 中
        // 4.2: DestructionAwareBeanPostProcessor 的 requiresDestruction()
        //   在 org.springframework.beans.factory.support.DisposableBeanAdapter.filterPostProcessors 和 org.springframework.beans.factory.support.DisposableBeanAdapter.hasApplicableProcessors 中


??????????????????????????????????????????????????????????????????????????????

# 有哪些常用的 BeanPostProcessor
1.AsyncAnnotationBeanPostProcessor: 用于在將 @Async 相應(yīng)的 Advisor 加入到對象的代理中
2.ScheduledAnnotationBeanPostProcessor: 用于處理 @Scheduled 注解, 將 bean 生產(chǎn)代理類
3.AnnotationAwareAspectJAutoProxyCreator: AOP 實(shí)現(xiàn)核心類
4.AutowiredAnnotationBeanPostProcessor: 用于處理 @Autowired 注解
5.ApplicationListenerDetector: 用于處理實(shí)現(xiàn) ApplicationListener 接口的 bean 對象, 將其添加到事件廣播器的監(jiān)聽者集合中.
...
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容