Demo
代碼十分簡單,整個工程結構以下:
pom
依賴<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
複製代碼
OrderService
、UserService
只加了@Service
註解,dao包下的兩個類OrderDao
、UserDao
只加了@Repository
註解。MainApplication
類中只寫main()
方法。代碼以下:public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = applicationContext.getBean(UserService.class);
System.out.println(userService);
OrderService orderService = applicationContext.getBean(OrderService.class);
System.out.println(orderService);
UserDao userDao = applicationContext.getBean(UserDao.class);
System.out.println(userDao);
OrderDao orderDao = applicationContext.getBean(OrderDao.class);
System.out.println(orderDao);
applicationContext.close();
}
複製代碼
AppConfig
類是一個配置類,類上加了兩個註解,加@Configuration
代表AppConfig
是一個配置類,加@ComponentScan
是爲了告訴Spring
要掃描哪些包,代碼以下:@Configuration
@ComponentScan("com.tiantang.study")
public class AppConfig {
}
複製代碼
MainApplication
中的main()
方法,這樣一個Spring
容器就運行起來了。控制檯分別打印出了UserService
、OrderService
、UserDao
、OrderDao
的hash
碼。xml
配置的方式,如今就這麼幾行簡單的代碼,一個Spring
容器就能運行起來,咱們就能從容器中獲取到Bean
,Spring
內部是如何作到的呢?下面就來逐步分析Spring
啓動的源碼。main()
方法,從代碼中能夠發現,核心代碼只有一行,new AnnotationConfigApplicationContext(AppConfig.class)
,經過這一行代碼,就將Spring
容器給建立完成,而後咱們就能經過getBean()
從容器中獲取到對象的了。所以,分析Spring
源碼,就從AnnotationConfigApplicationContext
的有參構造函數開始。AnnotationConfigApplicationContext
與ClassPathXmlApplicationContext
做用同樣,前者對應的是採用JavaConfig
技術的應用,後者對應的是XML
配置的應用Spring
源碼閱讀以前,須要先理解幾個概念。Spring
會將全部交由Spring
管理的類,掃描其class
文件,將其解析成BeanDefinition
,在BeanDefinition
中會描述類的信息,例如:這個類是不是單例的,Bean
的類型,是不是懶加載,依賴哪些類,自動裝配的模型。Spring
建立對象時,就是根據BeanDefinition
中的信息來建立Bean
。Spring
容器在本文能夠簡單理解爲DefaultListableBeanFactory
,它是BeanFactory
的實現類,這個類有幾個很是重要的屬性:beanDefinitionMap
是一個map
,用來存放bean
所對應的BeanDefinition
;beanDefinitionNames
是一個List
集合,用來存放全部bean
的name
;singletonObjects
是一個Map
,用來存放全部建立好的單例Bean
。Spring
中有不少後置處理器,但最終能夠分爲兩種,一種是BeanFactoryPostProcessor
,一種是BeanPostProcessor
。前者的用途是用來干預BeanFactory
的建立過程,後者是用來干預Bean
的建立過程。後置處理器的做用十分重要,bean
的建立以及AOP
的實現所有依賴後置處理器。AnnotationConfigApplicationContext
的構造函數的參數,是一個可變數組,能夠傳多個配置類,在本次Demo
中,只傳了AppConfig
一個類。this()
,在this()
中經過調用父類構造器初始化了BeanFactory
,以及向容器中註冊了7個後置處理器。而後調用register()
,將構造方法的參數放入到BeanDefinitionMap
中。最後執行refresh()
方法,這是整個Spring
容器啓動的核心,本文也將重點分析refresh()
方法的流程和做用。public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
// 會初始化一個BeanFactory,爲默認的DefaultListableBeanFactory
// 會初始化一個beanDefinition的讀取器,同時向容器中註冊了7個spring的後置處理器(包括BeanPostProcessor和BeanFactoryPostProcessor)
// 會初始化一個掃描器,後面彷佛並無用到這個掃描器,在refresh()中使用的是從新new的一個掃描器。
this();
// 將配置類註冊進BeanDefinitionMap中
register(annotatedClasses);
refresh();
}
複製代碼
this()
會調用AnnotationConfigApplicationContext
無參構造方法,而在Java
的繼承中,會先調用父類的構造方法。因此會先調用AnnotationConfigApplicationContext
的父類GeniricApplicationContext
的構造方法,在父類中初始化beanFactory
,即直接new
了一個DefaultListableBeanFactory
。public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
複製代碼
this()
中經過new AnnotatedBeanDefinitionReader(this)
實例化了一個Bean
讀取器,並向BeanDefinitionMap
中添加了7
個元素。經過new ClassPathBeanDefinitionScanner(this)
實例化了一個掃描器(該掃描器在後面並無用到)。public AnnotationConfigApplicationContext() {
// 此處會先調用父類的構造器,即先執行 super(),初始化DefaultListableBeanFactory
// 初始化了bean的讀取器,並向spring中註冊了7個spring自帶的類,這裏的註冊指的是將這7個類對應的BeanDefinition放入到到BeanDefinitionMap中
this.reader = new AnnotatedBeanDefinitionReader(this);
// 初始化掃描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
複製代碼
this.reader = new AnnotatesBeanDefinitionReader(this)
時,最後會調用到AnnotationConfigUtils.registerAnnotationConfigProcessors(BeanDefinitionRegistry registry,Object source)
方法,這個方法向BeanDefinitionMap
中添加了7
個類,這7
個類的BeanDefinition
(關於BeanDefinition
的介紹能夠參考前面的解釋)均爲RootBeanDefinition
,這幾個類分別爲ConfigurationClassPostProcessor
、AutowiredAnnotationBeanPostProcessor
、CommonAnnotationBeanPostProcessor
、RequiredAnnotationBeanPostProcessor
、PersistenceBeanPostProcessor
、EventListenerMethodProcessor
、DefaultEventListenerFactory
。ConfigurationClassPostProcessor
、AutowiredAnnotationBeanPostProcessor
、CommonAnnotationBeanPostProcessor
這三個類很是重要,這裏先在下面代碼中簡單介紹了一下做用,後面會單獨寫文章分析它們的做用。本文的側重點是先介紹完Spring
啓動的流程。public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
// 省略部分代碼 ...
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 註冊ConfigurationClassPostProcessor,這個類超級重要,它完成了對加了Configuration註解類的解析,@ComponentScan、@Import的解析。
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 註冊AutowiredAnnotationBeanPostProcessor,這個bean的後置處理器用來處理@Autowired的注入
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 註冊RequiredAnnotationBeanPostProcessor
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 註冊CommonAnnotationBeanPostProcessor,用來處理如@Resource,@PostConstruct等符合JSR-250規範的註解
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 註冊PersistenceAnnotationBeanPostProcessor,來用支持JPA
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 註冊EventListenerMethodProcessor,用來處理方法上加了@EventListener註解的方法
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
// 註冊DefaultEventListenerFactory,暫時不知道幹啥用的,從類名來看,是一個事件監聽器的工廠
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
複製代碼
this.scanner = new ClassPathBeanDefinitionScanner(this)
來初始化一個掃描器,這個掃描器在後面掃描包的時候,並無用到,猜想是Spring
爲了知足其餘的場景而初始化的,例如: 開發人員手動經過register(configClass)
時,掃描包時使用的。將傳入的配置類
annotatedClasses
解析成BeanDefinition
(實際類型爲AnnotatedGenericBeanDefinition
),而後放入到BeanDefinitionMap
中,這樣後面在ConfigurationClassPostProcessor
中能解析annotatedClasses
,例如demo
中的AppConfig
類,只有解析了AppConfig
類,才能知道Spring
要掃描哪些包(由於在AppConfig
類中添加了@ComponentScan
註解),只有知道要掃描哪些包了,才能掃描出須要交給Spring
管理的bean
有哪些,這樣才能利用Spring
來建立bean
。java
refresh()
方法是整個Spring
容器的核心,在這個方法中進行了bean
的實例化、初始化、自動裝配、AOP
等功能。下面先看看refresh()
方法的代碼,代碼中加了部分我的的理解,簡單介紹了每一行代碼做用,後面會針對幾個重要的方法作出詳細分析git
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 初始化屬性配置文件、檢驗必須屬性以及監聽器
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 給beanFactory設置序列化id
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 向beanFactory中註冊了兩個BeanPostProcessor,以及三個和環境相關的bean
// 這兩個後置處理器爲ApplicationContextAwareProcessor和ApplicationListenerDetector
// 前一個後置處理是爲實現了ApplicationContextAware接口的類,回調setApplicationContext()方法,
// 後一個處理器時用來檢測ApplicationListener類的,當某個Bean實現了ApplicationListener接口的bean被建立好後,會被加入到監聽器列表中
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 空方法,由子類實現
postProcessBeanFactory(beanFactory);
// 執行全部的BeanFactoryPostProcessor,包括自定義的,以及spring內置的。默認狀況下,容器中只有一個BeanFactoryPostProcessor,即:Spring內置的,ConfigurationClassPostProcessor(這個類很重要)
// 會先執行實現了BeanDefinitionRegistryPostProcessor接口的類,而後執行BeanFactoryPostProcessor的類
// ConfigurationClassPostProcessor類的postProcessorBeanFactory()方法進行了@Configuration類的解析,@ComponentScan的掃描,以及@Import註解的處理
// 通過這一步之後,會將全部交由spring管理的bean所對應的BeanDefinition放入到beanFactory的beanDefinitionMap中
// 同時ConfigurationClassPostProcessor類的postProcessorBeanFactory()方法執行完後,向容器中添加了一個後置處理器————ImportAwareBeanPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 註冊全部的BeanPostProcessor,由於在方法裏面調用了getBean()方法,因此在這一步,實際上已經將全部的BeanPostProcessor實例化了
// 爲何要在這一步就將BeanPostProcessor實例化呢?由於後面要實例化bean,而BeanPostProcessor是用來干預bean的建立過程的,因此必須在bean實例化以前就實例化全部的BeanPostProcessor(包括開發人員本身定義的)
// 最後再從新註冊了ApplicationListenerDetector,這樣作的目的是爲了將ApplicationListenerDetector放入到後置處理器的最末端
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 初始化MessageSource,用來作消息國際化。在通常項目中不會用到消息國際化
initMessageSource();
// Initialize event multicaster for this context.
// 初始化事件廣播器,若是容器中存在了名字爲applicationEventMulticaster的廣播器,則使用該廣播器
// 若是沒有,則初始化一個SimpleApplicationEventMulticaster
// 事件廣播器的用途是,發佈事件,而且爲所發佈的時間找到對應的事件監聽器。
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 執行其餘的初始化操做,例如和SpringMVC整合時,須要初始化一些其餘的bean,可是對於純spring工程來講,onFresh方法是一個空方法
onRefresh();
// Check for listener beans and register them.
// 這一步會將自定義的listener的bean名稱放入到事件廣播器中
// 同時還會將早期的ApplicationEvent發佈(對於單獨的spring工程來講,在此時不會有任何ApplicationEvent發佈,可是和springMVC整合時,springMVC會執行onRefresh()方法,在這裏會發佈事件)
registerListeners();
// 實例化剩餘的非懶加載的單例bean(注意:剩餘、非懶加載、單例)
// 爲何說是剩餘呢?若是開發人員自定義了BeanPosrProcessor,而BeanPostProcessor在前面已經實例化了,因此在這裏不會再實例化,所以這裏使用剩餘一詞
finishBeanFactoryInitialization(beanFactory);
// 結束refresh,主要乾了一件事,就是發佈一個事件ContextRefreshEvent,通知你們spring容器refresh結束了。
finishRefresh();
}
catch (BeansException ex) {
// 出異常後銷燬bean
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// 在bean的實例化過程當中,會緩存不少信息,例如bean的註解信息,可是當單例bean實例化完成後,這些緩存信息已經不會再使用了,因此能夠釋放這些內存資源了
resetCommonCaches();
}
}
}
複製代碼
refresh()
方法中,比較重要的方法爲invokeBeanFactoryPostProcessors(beanFactory)
和 finishBeanFactoryInitialization(beanFactory)
。其餘的方法相對而言比較簡單,下面主要分析這兩個方法,其餘方法的做用,能夠參考上面源碼中的註釋。BeanFactoryPostProcessor
,因爲Spring
會內置一個BeanFactoryPostProcessor
,即ConfigurationClassPostProcessor
(若是開發人員不自定義,默認狀況下只有這一個BeanFactoryPostProcessor
),這個後置處理器在處理時,會解析出全部交由Spring
容器管理的Bean
,將它們解析成BeanDefinition
,而後放入到BeanFactory
的BeanDefinitionMap
中。PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()
方法,主要做用是執行全部BeanFactoryPostProcessor
的postProcessorBeanFactory()
方法。BeanFactoryPostProcessor
又分爲兩種狀況,一種是直接實現BeanFactoryPostProcessor
接口的類,另外一種狀況是實現了BeanDefinitionRegistryPostProcessor
接口(BeanDefinitionRegistryPostProcessor
繼承了BeanFactoryPostProcessor
接口)。
BeanDefinitionRegistryPostProcessor
的postProcessorBeanDefinitionRegistry()
方法,而後再執行BeanFacotryPostProcessor
的postProcessorBeanFactory()
方法。public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
複製代碼
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
複製代碼
Spring
有一個內置的BeanFactoryPostProcessor
,即:ConfigurationClassPostProcessor
類,該類實現了BeanDefinitionRegistryPostProcessor
類,因此會執行ConfigurationClassPostProcessor.postProcessorBeanDefinitionRegistry
,ConfigurationClassPostProcessor
的UML
圖如上(刪減了部分不重要的繼承關係)BeanPostProcessor
,而後將這些BeanPostProcessor
實例化(會調用getBean()
方法,getBean()
方法的主要邏輯是,若是bean
存在於BeanFactory
中,則返回bean
;若是不存在,則會去建立。在後面會仔細分析getBean()
的執行邏輯)。將這些PostProcessor
實例化後,最後放入到BeanFactory
的beanPostProcessors
屬性中。BeanPostProcessor
? 包括Spring
內置的和開發人員自定義的。refresh()
方法中,會先執行完invokeBeanFactoryPostProcessor()
方法,這樣全部自定義的BeanPostProcessor
類均已經被掃描出並解析成BeanDefinition
(掃描和解析又是誰作的呢?ConfigurationClassPostProcessor
作的),存入至BeanFactory
的BeanDefinitionMap
,因此這兒能經過方法以下一行代碼找出全部的BeanPostProcessor
,而後經過getBean()
所有實例化,最後再將實例化後的對象加入到BeanFactory
的beanPostProcessors
屬性中,該屬性是一個List
集合。String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
複製代碼
ApplicationListenerDetector
,這樣作的目的是爲了將ApplicationListenerDetector
放入到後置處理器的最末端registerBeanPostProcessor()
最終調用的是PostProcessorRegistrationDelegate.registerBeanPostProcessors()
,下面是PostProcessorRegistrationDelegate.registerBeanPostProcessors()
方法的代碼public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 從BeanDefinitionMap中找出全部的BeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// ... 省略部分代碼 ...
// 分別找出實現了PriorityOrdered、Ordered接口以及普通的BeanPostProcessor
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 此處調用了getBean()方法,所以在此處就會實例化出BeanPostProcessor
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 將實現了PriorityOrdered接口的BeanPostProcessor添加到BeanFactory的beanPostProcessors集合中
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 下面這部分代碼與上面的代碼邏輯一致,是將實現了Ordered接口以及普通的BeanPostProcessor實例化以及添加到beanPostProcessors結合中,邏輯與處理PriorityOrdered的後置處理器同樣
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
// 最後將ApplicationListenerDetector這個後置處理器同樣從新放入到beanPostProcessor中,這樣作的目的是爲了將其放入到後置處理器的最末端
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
複製代碼
BeanPostProcessor
存在優先級,實現了PriorityOrdered
接口的優先級最高,其次是Ordered
接口,最後是普通的BeanPostProcessor
。優先級最高的,會最早放入到beanPostProcessors
這個集合的最前面,這樣在執行時,會最早執行優先級最高的後置處理器(由於List
集合是有序的)。BeanPostProcessor
執行,則可讓其實現PriorityOrdered
接口或者Ordered
接口。該方法初始化了一個事件廣播器,若是容器中存在了
beanName
爲applicationEventMulticaster
的廣播器,則使用該廣播器;若是沒有,則初始化一個SimpleApplicationEventMulticaster
。該事件廣播器是用來作應用事件分發的,這個類會持有全部的事件監聽器(ApplicationListener
),當有ApplicationEvent
事件發佈時,該事件監聽器能根據事件類型,檢索到對該事件感興趣的ApplicationListener
。github
initApplicationEventMulticaster()
方法的源碼以下(省略了部分日誌信息):protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 判斷spring容器中是否已經存在beanName = applicationEventMulticaster的事件廣播器
// 例如:若是開發人員本身註冊了一個
// 若是存在,則使用已經存在的;不然使用spring默認的:SimpleApplicationEventMulticaster
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
}
}
複製代碼
執行其餘的初始化操做,例如和
SpringMVC
整合時,須要初始化一些其餘的bean
,可是對於純Spring
工程來講,onRefresh()
方法是一個空方法。spring
這一步會將自定義的
listener
的bean
名稱放入到事件廣播器中,同時還會將早期的ApplicationEvent
發佈(對於單獨的Spring
工程來講,在此時不會有任何ApplicationEvent
發佈,可是和SpringMVC
整合時,SpringMVC
會執行onRefresh()
方法,在這裏會發佈事件)。方法源碼以下:docker
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 從BeanFactory中找到全部的ApplicationListener,可是不會進行初始化,由於須要在後面bean實例化的過程當中,讓全部的BeanPostProcessor去改造它們
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
// 將事件監聽器的beanName放入到事件廣播器中
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 發佈早期的事件(純的spring工程,在此時一個事件都沒有)
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
複製代碼
該方法十分重要,它完成了全部非懶加載的單例
Bean
的實例化和初始化,屬性的填充以及解決了循環依賴等問題。數據庫
Spring
建立Bean
的過程當中,是先將Bean
經過反射建立對象,而後經過後置處理器(BeanPostProcessor
)來爲對象的屬性賦值。因此這裏的實例化時指將Bean
建立出來,初始化是指爲bean
的屬性賦值)。finishBeanFactoryInitialization()
方法的代碼以下,bean
的建立和初始化均在beanFactory.preInstantiateSingletons()
中實現。protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化轉換服務
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 若是前面沒有註冊一個相似於PropertyPlaceholderConfigurer後置處理器的bean,那麼在這兒會註冊一個內置的屬性後置處理器
// 這兒主要是處理被加了註解的屬性
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
// 將BeanFactory的configurationFrozen屬性設置爲true,給frozenBeanDefinitionNames屬性賦值
// 目的是爲了避免讓在其餘的地方在修改bean的BeanDefinition
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 實例化剩下全部的非懶加載的單例
beanFactory.preInstantiateSingletons();
}
複製代碼
bean
是不是一個FactoryBean
,以及是否當即實例化FactoryBean
的getObject()
返回的對象,但最終均是調用getBean()
方法去實例化對象。在Bean
實例化、初始化完成後,會判斷Bean
是否實現了SmartSingletonInitializing
接口,若是實現了,則會調用該接口的afterSingletonInstantiated()
方法。Tips
:這裏提到了FactoryBean
,不是BeanFactory
。這二者名字很像,但做用倒是天差地別,有興趣的朋友能夠先本身Google
查下相關知識。這裏先簡單介紹一下,後續會單獨寫一篇文章介紹FactoryBean
,並經過FactoryBean
去解析Spring
與MyBatis
整合的原理。FactoryBean
是一個接口,該接口的實現類會向容器中註冊兩個bean
,一個是實現類自己所表明類型的對象,一個是經過重寫FactoryBean
接口中getObject()
方法所返回的bean
。以下例子中:會向容器中註冊兩個bean
,一個是MapperFactoryBean
自己,一個是UserMapper
。@Component
public class MapperFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
return new UserMapper();
}
@Override
public Class<?> getObjectType() {
return UserMapper.class;
}
}
複製代碼
bean
的實例化過程太過複雜,後面會結合流程圖去分析源碼。preInstantiatedSingletons()
方法的執行流程圖以下
preInstantiatedSingletons()
代碼以下public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
}
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判斷是不是factoryBean,若是是FactoryBean,則進行FactoryBean原生的實例化(非getObject()方法對應的對象)。
// 還須要判斷它是否當即實例化getObject()返回的對象,根據SmartFactoryBean的isEagerInit()的返回值判斷是否須要當即實例化
if (isFactoryBean(beanName)) {
// 首先實例化BeanFactory的原生對象,而後再根據isEagerInit()判斷是否實例化BeanFactory中getObject()返回的類型的對象
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
// 若是isEagerInit爲true,則當即實例化FactoryBean所返回的類型的對象
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// 在bean實例化以及屬性賦值完成後,若是bean實現了SmartInitializingSingleton接口,則回調該接口的方法
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
複製代碼
FactoryBean
仍是普通Bean
,最終都是調用getBean()
方法去建立bean
。getBean()
方法會調用doGetBean()
方法。public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
複製代碼
doGetBean()
方法當中,會先從緩存中獲取(即從singletonObjects
這個map
集合中獲取,爲何要先從緩存中獲取呢?由於要從Spring
容器獲取對象和建立對象,都是經過getBean()
方法,對於單例對象而言,對象只會被建立一次,那麼先從緩存中獲取對象,若是存在,則不用去新建立了,這樣就保證了單例對象只被建立一次)。若是緩存中存在,則接着調用getObjectForBeanInstance()
方法,而後返回bean
。若是緩存中不存在,則繼續往下執行。Bean
所對應的BeanDefinition
對象。接着判斷bean
有沒有依賴,String[] dependsOn = mbd.getDependsOn()
,若是有依賴的對象,那麼會先去實例化依賴的對象。getSingleton(beanName,lambda)
方法,這個方法的第二個參數是一個lambda
表達式,真正建立bean
的邏輯是在表達式的方法體中,即createBean()
方法,createBean()
方法會建立完成bean
,而後在getSingleton(beanName,lambda)
方法中會將建立完成的bean
存入到singletonObjects
屬性中。createBean()
後面分析。bean
後,最終仍會調用getObjectForBeanInstance()
。這個方法的邏輯比較簡單,先判斷bean
是不是一個FactoryBean
,若不是,則直接返回bean
;如果,則再判斷beanName
是不是以&符號開頭,若是是,表示獲取的是FactoryBean
的原生對象,則直接返回bean
;若不是以&符號開頭,則會返回FactoryBean
的getObject()
方法的返回值對象。doGetBean()
方法代碼以下protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
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 {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
// 標記bean爲已建立
// 並清除beanDefinition的緩存(mergedBeanDefinitions)
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 檢查bean是不是抽象類
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 保證當前bean所依賴的bean初始化
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// isDependent()方法用來判斷dep是否依賴beanName
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 保存下依賴關係
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
// 此時在getSingleton方法中傳入了一個lambda表達式,
// 此時不會當即執行lambda表達式,而是在調用這個lambda表達式的getObject()方法時纔開始執行lambda的方法體
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
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();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
複製代碼
getObjectForBeanInstance()
方法的做用是爲了根據beanName
來判斷是返回FactoryBean
原生對象仍是getObject()
方法所返回的對象.若beanName
以&符號開頭,則表示返回FactoryBean
原生對象,不然返回getObject()
方法所返回的對象。protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
// 若是不是一個FactoryBean對象或者是獲取FactoryBean的原生對象(原生對象指的是beanName是以&開頭)
// 此時能夠直接返回bean
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
// 若是是獲取FactoryBean的getObject()方法返回的類型對象,則須要進入到以下邏輯
// 對於getObject()方法,它返回的對象是在在第一次調用getObject方法時進行實例化的,實例化完成之後,會將結果緩存在factoryBeanObjectCache中
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 獲取FactoryBean返回的對象
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
複製代碼
doGetBean()
最終會調用createBean()
來建立bean
。createBean()
方法的代碼中,主要有兩行核心代碼:Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
複製代碼
resolveBeforeInstantiation()
方法在bean
實例化以前調用,在這個方法中執行了後置處理器InstantiationAwareBeanPostProcessor
的postProcessBeforeInstantiation()
方法,在bean
實例化以前對bean
進行處理。這個擴展點的意義十分重大,Spring
的AOP
就是在這兒實現的,感興趣的朋友可閱讀AnnotationAwareAspectJAutoProxyCreator
這個類的源碼,後續會單獨寫一篇文章進行分析。resolveBeforeInstantiation()
的返回值不爲null
,則直接將結果返回。若是爲null
,則會繼續執行方法doCreateBean()
。在doCreateBean()
方法中,進行了Bean
的實例化、屬性賦值、初始化等操做。createBean()
方法的流程圖
createBean()
方法的源代碼protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 第一次調用後置處理器(執行全部InstantiationAwareBeanPostProcessor的子類)
// 若是InstantiationAwareBeanPostProcessor的子類的postProcessBeforeInstantiation()方法返回值不爲空,表示bean須要被加強,
// 此時將不會執行後面的邏輯,AOP的實際應用就是在這兒實現的
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 第二次執行後置處理器的入口
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
複製代碼
doCreateBean()
方法會經過反射進行Bean
的建立,而後對bean
進行屬性填充(在填充屬性的同時,解決了循環依賴的問題),最後會對Bean
回調初始化相關的方法,例如:BeanPostProcessor.postProcessBeforeInilization(),InilizaingBean.afterPropertiesSet()
,給bean
配置的initMethod()
方法,以及BeanPostProcessor.postProcessAfterInilization()
。doCreateBean()
執行的流程圖以下: ![doCreateBean()方法流程圖]user-gold-cdn.xitu.io/2019/9/11/1…)doCreateBean()
方法的代碼(刪減了部分代碼)以下:protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 實例化bean(第二次執行後置處理器的入口),第二次執行後置處理器,主要是爲了推斷出實例化Bean所須要的構造器
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 此時bean對象已經建立成功,可是沒有設置屬性和通過其餘後置處理器處理
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 第三次執行後置處理器,緩存bean的註解元數據信息(用於後面在進行屬性填充時使用)
// 這一步對於CommonAnnotationBeanPostProcessor、AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor這一類處理器
// 主要是將bean的註解信息解析出來,而後緩存到後置處理器中的injectionMetadataCache屬性中
// 而對於ApplicationListenerDetector處理器,而是將bean是不是單例的標識存於singletonNames這個Map類型的屬性中
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
mbd.postProcessed = true;
}
}
// 判斷一個bean是否放入到singletonFactories中(提早暴露出來,能夠解決循環依賴的問題)
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 第四次出現後置處理器
// 獲取提早暴露的對象,能夠解決循環引用的問題,實際上提早暴露出來的bean是放入到了singletonFactories中,key是beanName,value是一個lambda表達式
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 填充屬性,第五次、第六次後置處理器入口
populateBean(beanName, mbd, instanceWrapper);
// 第七次、第八次執行後置處理器入口
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
}
return exposedObject;
}
複製代碼
createBeanInstance()
會經過反射建立對象時,會先執行後置處理器,經過調用後置處理器的deternineCondidateConstructors()
方法來推斷出使用哪個構造器來建立Bean
,典型的表明類有AutowiredAnnotationBeanPostProcessor
。bean
被經過反射建立完成後,會再次調用後置處理器MergedBeanDefinitionPostProcessor.postProcessMargedBeanDefinition()
方法,這一步執行後置處理器的目的是爲了找出加了@Autowired
、@Resource
等註解的屬性和方法,而後將這些註解信息緩存到injectionMetadataCache
屬性中,便於後面在bean
初始化階段(屬性賦值階段),根據@Autowired
等註解實現自動裝配。這一步的表明後置處理器有AutowiredAnnotationBeanPostProcessor
、CommonAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor
是用來處理Spring
提供的註解和JSR-330
中的部分註解,如:@Autowired
,@Value
,@Inject
。CommonAnnotationBeanPostProcessor
是用來處理JSR-250
中的註解,如@Resource
、@PostConstruct
、@PreDestroy
。編程
bean
(由於此時還未給bean
的屬性賦值,未完成自動裝配,所以稱之爲半成品)放入到DefaultSingletonBeanRegistry
類的singletonFactories
的屬性中,singletonFactories
屬性是一個Map
,key
爲beanName
,值爲ObjectFactory
類型(實際上就是一個lambda
表達式),當調用ObjectFactory
的getObject()
方法時,會執行lambda
表達式的方法體,在當前場景下,lambda
表達式的代碼以下,實際上就是執行了一次Bean
的後置處理器。這一步的目的是爲了解決bean
之間的循環依賴,到底是如何解決循環依賴的,之後分析。protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
// 調用後置處理的方法獲取bean早期暴露出來的bean對象(半成品)
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
複製代碼
populateBean()
方法,在該方法中又會執行兩次Bean
後置處理器,第一次執行後置處理器是爲了判斷Bean
是否須要繼續填充屬性,若是InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
方法返回的false
,則表示不進行屬性填充,bean
就不會進行@Autowired
等自動裝配過程,populateBean()
方法會直接結束。若返回true
,則會進行接下來的屬性填充,即會執行第二次後置處理器,InstantiationAwareBeanPostProcessor.postProcessPropertyValue()
方法,這一步的主角就是AutowiredAnnotationBeanPostProcessor
和CommonAnnotationBeanPostBeanPostProcessor
了,它們會根據前面緩存在injectionMetadataCache
中的註解信息來進行自動裝配。populateBean()
方法後後,接下來回執行initializeBean()
方法,即進入初始化階段。在initializeBean()
方法中,最早執行invokeAwareMethods()
方法,即執行Aware
接口的方法,如:BeanNameAware
、BeanClassLoaderAware
、BeanFactoryAware
。而後再一次執行全部Bean
後置處理器的BeanPostProcessor.postProcessBeforeInitialization()
方法。接着執行invokeInitMethods()
方法,在invokeInitMethods()
方法中,會執行InitializingBean
的afterPropertiesSet()
方法,和定義bean
時自定義的initMethod()
方法。最後再一次執行bean
後置處理器,BeanPostProcessor.postProcessAfterInitialization()
。bean
的實例化、初始化過程已經完成,建立好的bean
會被返回,如果單例bean
,最後會被存放到DefaultSingletonBeanRegistry
的singletonObjects
中。Spring
容器的啓動基本結束了,此時Bean
已經被實例化完成,且完成了自動裝配。執行finishRefresh()
方法,是爲了在容器refresh()
結束時,作一些其餘的操做,例如:發佈ContextRefreshedEvent
事件,這樣當咱們想在容器refresh
完成後執行一些特殊的邏輯,就能夠經過監聽ContextRefreshedEvent
事件來實現。Spring
內置了四個和應用上下文(ApplicationContextEvent
)有關的事件:ContextRefreshedEvent
、ContextStartedEvent
、ContextStopedEvent
、ContextClosedEvent
。protected void finishRefresh() {
clearResourceCaches();
initLifecycleProcessor();
getLifecycleProcessor().onRefresh();
// 發佈ContextRefreshedEvent
publishEvent(new ContextRefreshedEvent(this));
LiveBeansView.registerApplicationContext(this˛);
}
複製代碼
最後在
refresh()
方法的finally
語句塊中,執行了resetCommonCaches()
方法。由於在前面建立bean
時,對單例bean
的元數據信息進行了緩存,而單例bean
在容器啓動後,不會再進行建立了,所以這些緩存的信息已經沒有任何用處了,在這裏進行清空,釋放部份內存。數組
protected void resetCommonCaches() {
ReflectionUtils.clearCache();
AnnotationUtils.clearCache();
ResolvableType.clearCache();
CachedIntrospectionResults.clearClassLoader(getClassLoader());
}
複製代碼
Spring
的源碼分析中,能夠看出,啓動過程當中,bean
的建立過程最爲複雜,在建立過程當中,先後一共出現了8次調用BeanPostPorcessor
(實際上在bean
的整個生命週期中,一共會出現9
次調用後置處理器,第九次出如今bean
的銷燬階段。)Spring
的源碼,單例bean
的生命週期能夠總結爲以下一張圖
Spring
的啓動流程,經過AnnotationConfigApplicationContext
的有參構造方法入手,重點分析了this()
方法和refresh()
方法。在this()
中初始化了一個BeanFactory
,即DefaultListableBeanFactory
;而後向容器中添加了7個內置的bean
,其中就包括ConfigurationClassPostProcessor
。refresh()
方法中,又重點分析了invokeBeanFactoryPostProcessor()
方法和finishBeanFactoryInitialization()
方法。invokeBeanFactoryPostProcessor()
方法中,經過ConfigurationClassPostProcessor
類掃描出了全部交給Spring
管理的類,並將class
文件解析成對應的BeanDefinition
。finishBeanFactoryInitialization()
方法中,完成了非懶加載的單例Bean
的實例化和初始化操做,主要流程爲getBean()
——>doGetBean()
——>createBean()
——>doCreateBean()
。在bean
的建立過程當中,一共出現了8
次BeanPostProcessor
的執行,在這些後置處理器的執行過程當中,完成了AOP
的實現、bean
的自動裝配、屬性賦值等操做。Spring
中單例Bean
的生命週期。本文主要介紹了
Spring
的啓動流程,但對於一些地方的具體實現細節沒有展開分析,所以後續Spring源碼分析的計劃以下:緩存
ConfigurationClassPostProcessor
類如何掃描包,解析配置類。@Import
註解做用與@Enable
系列註解的實現原理JDK
動態代理與CGLIB
代理FactoryBean
的用途和源碼分析AutowiredAnnotationBeanPostProcessor
、CommonAnnotationBeanPostProcessor
如何實現自動裝配,Spring
如何解決循環依賴AOP
的實現原理SpringBoot
源碼分析Pepper-Metrics
地址: github.com/zrbcool/pep… GitHub
Pepper-Metrics
是坐我對面的兩位同事一塊兒開發的開源組件,主要功能是經過比較輕量的方式與經常使用開源組件(jedis/mybatis/motan/dubbo/servlet
)集成,收集並計算metrics
,並支持輸出到日誌及轉換成多種時序數據庫兼容數據格式,配套的grafana dashboard
友好的進行展現。項目當中原理文檔齊全,且所有基於SPI
設計的可擴展式架構,方便的開發新插件。另有一個基於docker-compose
的獨立demo
項目能夠快速啓動一套demo
示例查看效果https://github.com/zrbcool/pepper-metrics-demo
。若是你們以爲有用的話,麻煩給個star
,也歡迎你們參與開發,謝謝:)微信
歡迎掃描下方二維碼,關注微信公衆號:菜鳥飛呀飛 閱讀更多源碼,再也不面向搜索引擎編程