淺嘗Spring註解開發_Spring容器創建概述 淺嘗Spring註解開發,基於Spring 4.3.12 概述Spring容器創建的過程,包括12個方法的執行 淺嘗Spring註解開發_自定義註冊組件、屬性賦值、自動裝配 淺嘗Spring註解開發_Bean生命周期及執行過程 淺嘗Spring註解 ...
淺嘗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工廠)
:獲取新鮮的BeanFactory
ConfigurableListableBeanFactory 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
優先順序介面的BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry)
-
再執行實現了
Ordered
順序介面的BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry)
-
最後執行沒有實現任何優先順序或者是順序介面的
BeanDefinitionRegistryPostProcessors
postProcessor.postProcessBeanDefinitionRegistry(registry)
-
-
再執行
BeanFactoryPostProcessor
的方法-
獲取所有的
BeanFactoryPostProcessor
-
看先執行實現了
PriorityOrdered
優先順序介面的BeanFactoryPostProcessor
postProcessor.postProcessBeanFactory()
-
再執行實現了
Ordered
順序介面的BeanFactoryPostProcessor
postProcessor.postProcessBeanFactory()
-
最後執行沒有實現任何優先順序或者是順序介面的
BeanFactoryPostProcessor
postProcessor.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
,如果沒有自己創建一個DelegatingMessageSource
MessageSource
:取出國際化配置文件中的某個key的值;能按照區域信息獲取 -
把創建好的
MessageSource
註冊在容器中,以後獲取國際化配置文件的值的時候,可以自動註入MessageSource
beanFactory.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】
applyBeanPostProcessorsAfterInitialization
BeanPostProcessor.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)
-