1. 一些疑問(wèn)
- @Component,@Service,@Controller,@Repository@Bean等注解怎么實(shí)現(xiàn)的?
- @Autowired,@Resource 是怎么自動(dòng)裝配的贿堰?
- @ComponentScan 為什么就可以掃描注冊(cè)Bean
2. IOC 容器 示意圖
Spring IOC :
- Bean定義的定位,Bean 可能定義在XML中析藕,或者一個(gè)注解,或者其他形式批狱。這些都被用Resource來(lái)定位, 讀取Resource獲取BeanDefinition 注冊(cè)到 Bean定義注冊(cè)表中。
- 第一次向容器getBean操作會(huì)觸發(fā)Bean的創(chuàng)建過(guò)程,實(shí)列化一個(gè)Bean時(shí) ,根據(jù)BeanDefinition中類(lèi)信息等實(shí)列化Bean.
- 將實(shí)列化的Bean放到單列Bean緩存內(nèi)。
- 此后再次獲取向容器getBean就會(huì)從緩存中獲取输枯。
3. 容器的refresh方法
方法定義在AbstractApplicationContext 中,
public void refresh() throws BeansException, IllegalStateException {
//同步代碼塊 占贫。
synchronized (this.startupShutdownMonitor) {
// 準(zhǔn)備刷新.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
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...
resetCommonCaches();
}
}
prepareRefresh 準(zhǔn)備刷新
- 設(shè)置啟動(dòng)時(shí)間,設(shè)計(jì)容器激活標(biāo)志(active=true)
- 初始化 properties 資源
- 驗(yàn)證必須存在的properties(validateRequiredProperties)
- 初始earlyApplicationEnvents.用于收集已經(jīng)產(chǎn)生的ApplicationEnvents.
obtainFreshBeanFactory 獲取容器
- 調(diào)用子類(lèi)的refeshBeanFactory(),SpringBoot中采用默認(rèn)的實(shí)現(xiàn),設(shè)置BeanFactory的SerializationId,設(shè)置refreshed標(biāo)志為true型奥。
- 獲取BeanFactory
- XmlWebApplicationContext 瞳收,AnnotationConfigApplicationContext 會(huì)在這一步加載BeanDefinition
prepareBeanFactory 為了接下來(lái)使用BeanFactory 做準(zhǔn)備
為BeanFactory 做些標(biāo)準(zhǔn)的設(shè)置
為內(nèi)部的BeanFactory設(shè)置類(lèi)加載器
設(shè)置表達(dá)式解析器厢汹,屬性編輯器螟深。
-
注冊(cè)BeanPostProcessor(ApplicationContextAwareProcessor,ApplicationListenerDetector),
- ApplicationContextAwareProcessor:對(duì)Spring 中各種Aware接口的支持,在初始化Bean前,調(diào)用Bean實(shí)現(xiàn)的Aware接口方法烫葬。
- ApplicationListenerDetector:用于收集實(shí)現(xiàn)了ApplicationListener接口的Bean
-
注冊(cè)指定的依賴(lài)類(lèi)型和對(duì)應(yīng)的value,
- 例如:beanFactory.registerResolvableDependency(ResourceLoader.class, this);那么在類(lèi)中自動(dòng)注入ResourceLoader類(lèi)型的對(duì)象界弧,就會(huì)拿到當(dāng)前IOC容器。
注入一些其它信息的bean搭综,比如environment垢箕、systemProperties等
postProcessBeanFactory 后處理BeanFactory
用于在BeanFactory 完成標(biāo)準(zhǔn)的初始化之后修改BeanFactory。不同容器根據(jù)自己的需求添加特殊的后置處理器兑巾,
EmbeddedWebApplicationContext 容器在這里添加了對(duì)ServletContextAware支持的Bean后置處理器(WebApplicationContextServletContextAwareProcessor)条获。
invokeBeanFactoryPostProcessors 執(zhí)行BeanFactory后置處理器。
實(shí)例化并且執(zhí)行所有已經(jīng)注冊(cè)到BeanFactory中的 BeanFactoryPostProcessor蒋歌。支持按照Order排序帅掘。
- 執(zhí)行邏輯
調(diào)用PostProcessorRegistrationDelegate的靜態(tài)方法invokeBeanFactoryPostProcessors,
執(zhí)行順序:
1.執(zhí)行ApplicationContext初始化器注冊(cè)的BeanDefinitionRegistryPostProcessor類(lèi)型的處理器
2.執(zhí)行實(shí)現(xiàn)了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor委煤。
3.執(zhí)行實(shí)現(xiàn)了Ordered的BeanDefinitionRegistryPostProcessor
4.執(zhí)行 所有后置處理器的 BeanFactoryPostProcessor 的接口方法
5.獲取所有的BeanFactoryPostProcessor,排除已經(jīng)執(zhí)行過(guò)得后置處理器。
6.按照2-4的順序 執(zhí)行所有未執(zhí)行的BeanFactoryPostProcessor修档。
- 介紹BeanFactoryPostProcessor 接口
針對(duì)BeanFactory 的處理,允許使用者修改容器中的bean definitions,例如:
ServletComponentRegisteringPostProcessor提供對(duì)@WebFilter,@WebServlet,@WebListener注解的掃描碧绞,并注冊(cè)到容器中。
ConfigurationClassPostProcessor 對(duì)所有的@Configuration類(lèi)進(jìn)行動(dòng)態(tài)代理的增強(qiáng)吱窝。
注意使用時(shí)不能對(duì)任何BeanDefinition 進(jìn)行實(shí)列化操作头遭。
- 介紹BeanDefinitionRegistryPostProcessor 接口
繼承自BeanFactoryPostProcessor,針對(duì)BeanDefinitionRegistry的后置處理器,會(huì)先于BeanFactoryPostProcessor 執(zhí)行癣诱。
- ConfigurationClassPostProcessor
ConfigurationClassPostProcessor后置處理器 實(shí)現(xiàn)了 PriorityOrdered接口计维,優(yōu)先級(jí)最高的后置處理器,在SpringBoot自動(dòng)配置的實(shí)現(xiàn)中起到舉足輕重的作用撕予。是自動(dòng)配置功能的驅(qū)動(dòng)著,如果沒(méi)有他那些神奇的自動(dòng)配置注解都不在起作用,對(duì)@Configuration,@Bean,@ComponentScan,@Import,@ImportResource,@PropertySource注解解析鲫惶。
1. 處理PropertySources 注解
加載property資源
2. 處理ComponentScans和ComponentScan注解
掃描指定包下所有@Component注解。包括@Service实抡,@Controller,@Repository,@Configuration,@ManagedBean
3. 處理@Import注解類(lèi)
解析所有包含@Import注解欠母。spring中@Enable****注解的實(shí)現(xiàn)依賴(lài)。@Import的value 有兩種類(lèi)型的Class.
3.1 ImportSelector 導(dǎo)入選擇器吆寨。
執(zhí)行非DeferredImportSelector接口的赏淌,收集配置類(lèi)。
收集DeferredImportSelector接口的實(shí)現(xiàn)啄清。稍后執(zhí)行六水。
3.2 ImportBeanDefinitionRegistrar 導(dǎo)入類(lèi)定義注冊(cè)者
收集ImportBeanDefinitionRegistrar對(duì)象。
3.3 如果不是上面兩種類(lèi)型 就會(huì)被當(dāng)作普通的configuration 類(lèi) 注冊(cè)到容器辣卒。
例如@EnableScheduling
4. 處理ImportResource注解
收集@ImportResource中指定的配置文件信息瞭亮。
5. 收集@Bean注解的方法
6. 處理接口默認(rèn)方法
7. 處理父類(lèi)
父類(lèi)className 不是"java"開(kāi)頭灾杰,并且是未處理過(guò)的類(lèi)型唉擂。獲取父類(lèi)循環(huán)1-7睁本。
8. 處理3.1中收集的DeferredImportSelector。
9.利用ConfigurationClassBeanDefinitionReader 處理每個(gè)Configuration類(lèi)的@Bean和第4步收集的資源和3.2中收集的注冊(cè)者啡莉。
registerBeanPostProcessors 注冊(cè)bean后置處理器
-
委托給PostProcessorRegistrationDelegate的靜態(tài)方法registerBeanPostProcessors執(zhí)行
1.1 按照 PriorityOrdered港准,Ordered,普通,MergedBeanDefinitionPostProcessor 添加到 beanFactory 的beanPostProcessors屬性中咧欣。最后添加ApplicationListenerDetector浅缸。
BeanPostProcessors 接口
該接口在Bean的實(shí)列話過(guò)程中被調(diào)用,在對(duì)一個(gè)對(duì)象進(jìn)行初始化 前后 被調(diào)用。
例如:實(shí)現(xiàn)了 EnvironmentAware,EmbeddedValueResolverAware该押,ResourceLoaderAware疗杉,ApplicationContextAware等Aware就是這個(gè)時(shí)候 被執(zhí)行的。
- MergedBeanDefinitionPostProcessor 接口
? 該接口繼承了BeanPostProcessors接口, 會(huì)在 bean 實(shí)列化 之后 屬性注入前 執(zhí)行蚕礼。例如 對(duì)@Autowired @Resource @Value 注解的解析烟具。
initMessageSource
在Spring容器中初始化一些國(guó)際化相關(guān)的屬性。
initApplicationEventMulticaster
在容器中初始化Application事件廣播器奠蹬。
onRefresh
onRefresh是一個(gè)模板方法朝聋,留給子類(lèi)容器擴(kuò)贊,不同的容器做不同的事情囤躁。
例如:容器AnnotationConfigEmbeddedWebApplicationContext中會(huì)調(diào)用createEmbeddedServletContainer方法去創(chuàng)建內(nèi)置的Servlet容器冀痕。
EmbeddedServletContainerAutoConfiguration 類(lèi)中定義了 Spring boot 支持的三種 Servlet容器。
目前SpringBoot只支持3種內(nèi)置的Servlet容器:
- Tomcat
- Jetty
- Undertow
registerListeners
- 將所有的 ApplicationListener 實(shí)現(xiàn)類(lèi)注冊(cè) 到 ApplicationEventMulticaster中,覺(jué)得是觀察者模式狸演。
- 把已經(jīng)產(chǎn)生的事件廣播出去言蛇。
finishBeanFactoryInitialization
實(shí)列化所有 非懶加載的 類(lèi)。
finishRefresh
- 完成容器的初始化過(guò)程,發(fā)布相應(yīng)事件宵距。
- 啟動(dòng)容器的聲明周期處理器腊尚。管理容器聲明周期。
- 發(fā)布 ContextRefreshedEvent事件满哪。
- 啟動(dòng)內(nèi)嵌的Servlet容器婿斥。
- 發(fā)布容器啟動(dòng)事件。