淺嘗Spring注解開發_Spring容器創建概述
淺嘗Spring注解開發,基于Spring 4.3.12
概述Spring容器創建的程序,包括12個方法的執行
淺嘗Spring注解開發_自定義注冊組件、屬性賦值、自動裝配
淺嘗Spring注解開發_Bean生命周期及執行程序
淺嘗Spring注解開發_AOP原理及完整程序分析(原始碼)
淺嘗Spring注解開發_宣告式事務及原理
淺嘗Spring注解開發_簡單理解BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener
Spring注解開發_Spring容器創建概述
概述12個方法
//獲取ioc容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfPropertyValues.class);
/**
* 創建一個新的AnnotationConfigApplicationContext,派生bean定義
* 從給定的帶注釋的類,并自動重繪背景關系,
* @param 類一個或多個帶注釋的類
* e.g. {@link Configuration @Configuration} classes
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 為重繪準備此背景關系,
prepareRefresh();
// 告訴子類重繪內部bean工廠,
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 準備在此背景關系中使用bean工廠,
prepareBeanFactory(beanFactory);
try {
// 允許在背景關系子類中對bean工廠進行后處理,
postProcessBeanFactory(beanFactory);
// 呼叫在背景關系中注冊為bean的工廠處理器,
invokeBeanFactoryPostProcessors(beanFactory);
// 注冊攔截bean創建的bean處理器,
registerBeanPostProcessors(beanFactory);
// 初始化此背景關系的訊息源,
initMessageSource();
// 為此背景關系初始化事件多播,
initApplicationEventMulticaster();
// 在特定的背景關系子類中初始化其他特殊bean,
onRefresh();
// 檢查監聽器bean并注冊它們,
registerListeners();
// 實體化所有剩余的(非lazy-init)單例,
finishBeanFactoryInitialization(beanFactory);
// 最后一步:發布相應的事件,
finishRefresh();
}
//...
BeanFactory預處理
BeanFactory的創建及預準備作業
- BeanFactory 的作用是負責 bean 的創建、依賴注入和初始化,bean 的各項特征由 BeanDefinition 定義
- BeanDefinition 作為 bean 的設計藍圖,規定了 bean 的特征,如單例多例、依賴關系、初始銷毀方法等
- BeanDefinition 的來源有多種多樣,可以是通過 xml 獲得、配置類獲得、組件掃描獲得,也可以是編程添加
- 所有的 BeanDefinition 會存入 BeanFactory 中的 beanDefinitionMap 集合
1、this()
- 先呼叫父類構造器
- 宣告兩個類,通過讀取注解或者掃描類路徑讀取
BeanDefinition - 初始化了DefaultListableBeanFactory:基于bean定義元資料的成熟bean工廠,可通過后處理器進行擴展,內部定義了
BeanDefinition的Map屬性名beanDefinitionMap,可以操作bean - 注冊了多個(6個)默認的后置處理器
2、register(annotatedClasses)
- 校驗傳入的
JavaConfig.class配置類的注解(是否需要忽略) - 處理通用注解
- 封裝為
BeanDefinitionHolder后,注冊到容器中 - 相當于將JavaConfig配置類作為一個Bean注冊到容器中
3、Spring容器的refresh():創建重繪
prepareRefresh():重繪前的預處理initPropertySources()[初始化屬性源]:初始化一些屬性設定,空方法,留給子類自定義個性化的屬性設定方法getEnvironment().validateRequiredProperties():檢驗屬性的合法等earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>():保存容器中的一些早期的事件,一旦多播機可用就會發布
obtainFreshBeanFactory()(//告訴子類重繪內部Bean工廠):獲取新鮮的BeanFactoryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()類注釋://大多數可列出的bean工廠要實作的配置介面, 除了 {@link ConfigurableBeanFactory} 之外,它還提供了以下工具: 分析和修改 bean 定義,并預實體化單例,refreshBeanFactory():重繪[創建]BeanFactory- 創建了一個
this.beanFactory = new DefaultListableBeanFactory(),補充:這個方法在創建AnnotationConfigApplicationContext的父類GenericApplicationContext的無參構造時呼叫了,注釋是//創建一個新的 GenericApplicationContext - 設定id
- 創建了一個
getBeanFactory():回傳剛才GenericApplicationContext創建的BeanFactory物件- 將創建的
BeanFactory[型別:DefaultListableBeanFactory]回傳
prepareBeanFactory(beanFactory):BeanFactory的預準備作業(BeanFactory進行一些設定)- 設定
BeanFactory的類加載器、支持運算式決議器... - 添加部分
BeanPostProcessor[型別:ApplicationContextAwareProcessor] - 設定忽略的自動裝配的介面
EnvironmentAware、EmbeddedValueResolverAware、xxx... - 注冊可以決議的自動裝配;我們能直接在任何組件中自動注入:
BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext... - 添加
BeanPostProcessor[型別:ApplicationListenerDetector],將用于檢測內部 bean 的早期后處理器注冊為ApplicationListener - 添加編譯時的
AspectJ - 給
BeanFactory中注冊一些能用的組件;ConfigurableEnvironment environment:application背景關系環境Map<String, Object> systemProperties:系統屬性Map<String, Object> systemEnvironment:系統環境變數
- 設定
postProcessBeanFactory(beanFactory):BeanFactory準備作業完成后進行的后置處理作業- 子類通過重寫這個方法來在
BeanFactory創建并預準備完成以后做進一步的設定
- 子類通過重寫這個方法來在
執行BeanFactoryPostProcessor
BeanFactoryPostProcessor是beanFactory的后置處理器
BeanFactoryPostProcessor是beanFactory的后置處理器,在BeanFactory標準初始化之后呼叫,來定制和修改BeanFactory的內容,所有的bean定義已經保存加載到beanFactory,但是bean的實體還未創建
執行BeanFactoryPostProcessor分兩步,先執行BeanDefinitionRegistryPostProcessor,后執行BeanFactoryPostProcessor
-
invokeBeanFactoryPostProcessors(beanFactory):執行BeanFactoryPostProcessor的方法,BeanFactoryPostProcessor:BeanFactory的后置處理器,在BeanFactory標準初始化(以上4步)之后執行的,兩個介面:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor-
執行
BeanFactoryPostProcessor的方法-
先執行
BeanDefinitionRegistryPostProcessor-
獲取所有的
BeanDefinitionRegistryPostProcessor -
看先執行實作了
PriorityOrdered優先級介面的BeanDefinitionRegistryPostProcessorpostProcessor.postProcessBeanDefinitionRegistry(registry) -
再執行實作了
Ordered順序介面的BeanDefinitionRegistryPostProcessorpostProcessor.postProcessBeanDefinitionRegistry(registry) -
最后執行沒有實作任何優先級或者是順序介面的
BeanDefinitionRegistryPostProcessorspostProcessor.postProcessBeanDefinitionRegistry(registry)
-
-
再執行
BeanFactoryPostProcessor的方法-
獲取所有的
BeanFactoryPostProcessor -
看先執行實作了
PriorityOrdered優先級介面的BeanFactoryPostProcessorpostProcessor.postProcessBeanFactory() -
再執行實作了
Ordered順序介面的BeanFactoryPostProcessorpostProcessor.postProcessBeanFactory() -
最后執行沒有實作任何優先級或者是順序介面的
BeanFactoryPostProcessorpostProcessor.postProcessBeanFactory()
-
-
-
注冊BeanPostProcessor
按照優先級注冊后置處理器,不執行
-
registerBeanPostProcessors(beanFactory):注冊BeanPostProcessor(Bean的后置處理器)攔截Bean的創建不同介面型別的
BeanPostProcessor,在Bean創建前后的執行時機是不一樣的-
BeanPostProcessor后置處理器 -
DestructionAwareBeanPostProcessor銷毀感知后置處理器 -
InstantiationAwareBeanPostProcessor實體化感知后置處理器 -
SmartInstantiationAwareBeanPostProcessor智能實體化感知后置處理器 -
MergedBeanDefinitionPostProcessor[internalPostProcessors]合并Bean定義資訊后置處理器
-
獲取所有的
BeanPostProcessor,后置處理器都默認可以通過PriorityOrdered、Ordered介面來執行優先級 -
先注冊
PriorityOrdered優先級介面的BeanPostProcessor把每一個
BeanPostProcessor添加到BeanFactory中,beanFactory.addBeanPostProcessor(postProcessor) -
再注冊
Ordered介面的 -
最后注冊沒有實作任何優先級介面的
-
最終注冊
MergedBeanDefinitionPostProcessor -
注冊一個
ApplicationListenerDetector,來在Bean創建完成后檢查是否是ApplicationListener,如果是就添加組件applicationContext.addApplicationListener((ApplicationListener<?>) bean)
-
初始化MessageSource
國際化
-
initMessageSource():初始化MessageSource組件(做國際化功能;訊息系結,訊息決議)-
獲取
BeanFactory -
看容器中是否有id為
messageSource的,型別是MessageSource的組件,如果有賦值給messageSource,如果沒有自己創建一個DelegatingMessageSourceMessageSource:取出國際化組態檔中的某個key的值;能按照區域資訊獲取 -
把創建好的
MessageSource注冊在容器中,以后獲取國際化組態檔的值的時候,可以自動注入MessageSourcebeanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)MessageSource.getMessage(String code, Object[] args, String defaultMessage, Locale locale)
-
初始化事件派發器、監聽器
-
initApplicationEventMulticaster():初始化事件派發器- 獲取
BeanFactory - 從
BeanFactory中獲取applicationEventMulticaster的ApplicationEventMulticaster - 如果上一步沒有配置,就創建一個
SimpleApplicationEventMulticaster - 將創建的
ApplicationEventMulticaster添加到BeanFactory中,以后其他組件直接自動注入
- 獲取
-
onRefresh():留給子容器(子類)- 子類重寫這個方法,在容器重繪的時候可以自定義邏輯;
-
registerListeners():給容器中將所有專案里面的ApplicationListener注冊進來;-
從容器中拿到所有的
ApplicationListener -
將每個監聽器添加到事件派發器中
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName) -
派發之前步驟產生的事件
-
創建Bean準備、完成
有代理物件就用,沒有就創建,然后在初始化前后準備各種后置處理器,創建完成后放入各種Map
-
finishBeanFactoryInitialization(beanFactory):初始化所有剩下的單實體bean-
beanFactory.preInstantiateSingletons():初始化剩下的單實體bean-
獲取容器中的所有Bean,依次進行初始化和創建物件
-
獲取Bean的定義資訊:
RootBeanDefinition -
判斷Bean不是抽象的,是單實體的,不是懶加載
-
判斷是否是
FactoryBean,是否是實作FactoryBean介面的Bean -
如果不是工廠Bean,利用
getBean(beanName):創建物件-
這個
getBean(beanName)就是平時測驗類中用到的ioc.getBean() -
doGetBean(name, null, null, false) -
先獲取快取中保存的單實體Bean,
this.singletonObjects.get(beanName),如果能獲取到說明這個Bean之前被創建過(所有創建過的單實體Bean都會被快取起來)可以從
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256)屬性獲取到 -
快取中獲取不到,開始Bean的創建物件流程,使用
BeanFactory -
標記當前bean已經被創建
markBeanAsCreated(beanName) -
獲取Bean的定義資訊
-
【獲取當前Bean依賴的其他Bean,
mbd.getDependsOn(),如果有按照就getBean()把依賴的Bean先創建出來】 -
啟動單實體Bean的創建流程
-
進入匿名類的
createBean(beanName, mbd, args)方法(可以打斷點進入) -
Object bean = resolveBeforeInstantiation(beanName, mbdToUse)[給 BeanPostProcessors 一個回傳代理而不是目標 Bean 實體的機會]:讓BeanPostProcessor先攔截回傳代理物件【
InstantiationAwareBeanPostProcessor提前執行,就是在AOP中先于BeanPostProcessor執行的那個組件】- 先觸發:
postProcessBeforeInstantiation()實體化前的后處理 - 如果有回傳值,觸發:
postProcessAfterInitialization()初始化后的后處理
- 先觸發:
-
如果前面的
InstantiationAwareBeanPostProcessor沒有回傳代理物件,呼叫第4步創建Bean -
Object beanInstance = doCreateBean(beanName, mbdToUse, args):創建Bean-
【創建Bean實體】:
createBeanInstance(beanName, mbd, args)利用工廠方法或者物件的構造器創建出Bean實體
-
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)[允許后處理器修改合并的 Bean 定義,]呼叫
MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName) -
【Bean屬性賦值】
populateBean(beanName, mbd, instanceWrapper)賦值之前:
-
拿到
InstantiationAwareBeanPostProcessor后置處理器:postProcessAfterInstantiation()實體化后的后處理(對應上面(8.2)) -
拿到
InstantiationAwareBeanPostProcessor后置處理器:ibp.postProcessPropertyValues()后處理屬性值
開始賦值:
-
應用Bean屬性的值;為屬性利用setter方法等進行賦值:
applyPropertyValues(beanName, mbd, bw, pvs)
-
-
【Bean初始化】
initializeBean(beanName, exposedObject, mbd):-
【執行Aware介面方法】
invokeAwareMethods(beanName, bean):執行xxxAware介面的方法,如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware -
【在初始化之前應用 BeanPostProcessors】
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)BeanPostProcessor.postProcessBeforeInitialization() -
【執行初始化方法】
invokeInitMethods(beanName, wrappedBean, mbd)- 是否是
InitializingBean介面的實作;執行介面規定的初始化 - 是否自定義初始化方法
- 是否是
-
【在初始化之后應用 BeanPostProcessors】
applyBeanPostProcessorsAfterInitializationBeanPostProcessor.postProcessAfterInitialization()
-
-
注冊Bean的銷毀方法
-
-
將創建的Bean添加到快取中
singletonObjects
-
-
-
-
-
ioc容器就是這些Map,很多的Map里面保存了單實體Bean,環境資訊...
所有Bean都利用getBean創建完成以后:檢查所有的Bean是否是SmartInitializingSingleton[智能初始化單例]介面的,如果是,就執行afterSingletonsInstantiated()在單例實體化之后
容器創建完成
-
finishRefresh():完成BeanFactory的初始化創建作業,IOC容器就創建完成-
initLifecycleProcessor():初始化和生命周期有關的后置處理器:LifecycleProcessor-
默認從容器中找是否有
lifecycleProcessor的組件【LifecycleProcessor】; -
如果沒有
new DefaultLifecycleProcessor(); -
加入到容器
onRefresh()寫一個
LifecycleProcessor的實作類,可以在BeanFactory的生命周期onRefresh()、onClose()處攔截
-
-
getLifecycleProcessor().onRefresh()拿到前面定義的生命周期處理器(
BeanFactory),回呼onRefresh() -
publishEvent(new ContextRefreshedEvent(this)):發布容器重繪完成事件 -
LiveBeansView.registerApplicationContext(this)
-
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/469701.html
標籤:其他
