Spring源碼系列之容器啓動

Spring啓動流程


目錄

1. Demo建立

  • Demo代碼十分簡單,整個工程結構以下:
    Demo工程結構圖
  • pom依賴
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.8.RELEASE</version>
</dependency>
複製代碼
  • service包下的兩個類OrderServiceUserService只加了@Service註解,dao包下的兩個類OrderDaoUserDao只加了@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 {
}
複製代碼

2. 啓動

  • 運行MainApplication中的main()方法,這樣一個Spring容器就運行起來了。控制檯分別打印出了UserServiceOrderServiceUserDaoOrderDaohash碼。
  • 那麼問題來了,相比以往xml配置的方式,如今就這麼幾行簡單的代碼,一個Spring容器就能運行起來,咱們就能從容器中獲取到BeanSpring內部是如何作到的呢?下面就來逐步分析Spring啓動的源碼。

3. 入口

  • 程序的入口爲main()方法,從代碼中能夠發現,核心代碼只有一行,new AnnotationConfigApplicationContext(AppConfig.class),經過這一行代碼,就將Spring容器給建立完成,而後咱們就能經過getBean()從容器中獲取到對象的了。所以,分析Spring源碼,就從AnnotationConfigApplicationContext的有參構造函數開始。
  • AnnotationConfigApplicationContextClassPathXmlApplicationContext做用同樣,前者對應的是採用JavaConfig技術的應用,後者對應的是XML配置的應用

4. 基礎概念

  • 在進行Spring源碼閱讀以前,須要先理解幾個概念。
    1. Spring會將全部交由Spring管理的類,掃描其class文件,將其解析成BeanDefinition,在BeanDefinition中會描述類的信息,例如:這個類是不是單例的,Bean的類型,是不是懶加載,依賴哪些類,自動裝配的模型。Spring建立對象時,就是根據BeanDefinition中的信息來建立Bean
    1. Spring容器在本文能夠簡單理解爲DefaultListableBeanFactory,它是BeanFactory的實現類,這個類有幾個很是重要的屬性:beanDefinitionMap是一個map,用來存放bean所對應的BeanDefinitionbeanDefinitionNames是一個List集合,用來存放全部beannamesingletonObjects是一個Map,用來存放全部建立好的單例Bean
    1. Spring中有不少後置處理器,但最終能夠分爲兩種,一種是BeanFactoryPostProcessor,一種是BeanPostProcessor。前者的用途是用來干預BeanFactory的建立過程,後者是用來干預Bean的建立過程。後置處理器的做用十分重要,bean的建立以及AOP的實現所有依賴後置處理器。

5. AnnotationConfigApplicationContext的構造方法

  • 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();
}
複製代碼
5.1 this()調用
  • 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,這幾個類分別爲ConfigurationClassPostProcessorAutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorRequiredAnnotationBeanPostProcessorPersistenceBeanPostProcessorEventListenerMethodProcessorDefaultEventListenerFactory
  • 這7個類中,ConfigurationClassPostProcessorAutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor這三個類很是重要,這裏先在下面代碼中簡單介紹了一下做用,後面會單獨寫文章分析它們的做用。本文的側重點是先介紹完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)時,掃描包時使用的。
5.2 register(annotatedClasses)

將傳入的配置類annotatedClasses解析成BeanDefinition(實際類型爲AnnotatedGenericBeanDefinition),而後放入到BeanDefinitionMap中,這樣後面在ConfigurationClassPostProcessor中能解析annotatedClasses,例如demo中的AppConfig類,只有解析了AppConfig類,才能知道Spring要掃描哪些包(由於在AppConfig類中添加了@ComponentScan註解),只有知道要掃描哪些包了,才能掃描出須要交給Spring管理的bean有哪些,這樣才能利用Spring來建立beanjava

5.3 執行refresh()方法

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();
		}
	}
}
複製代碼

6. refresh()方法

  • refresh()方法中,比較重要的方法爲invokeBeanFactoryPostProcessors(beanFactory)finishBeanFactoryInitialization(beanFactory)。其餘的方法相對而言比較簡單,下面主要分析這兩個方法,其餘方法的做用,能夠參考上面源碼中的註釋。
6.1 invokeBeanFactoryPostProcessors()
  • 該方法的做用是執行全部的BeanFactoryPostProcessor,因爲Spring會內置一個BeanFactoryPostProcessor,即ConfigurationClassPostProcessor(若是開發人員不自定義,默認狀況下只有這一個BeanFactoryPostProcessor),這個後置處理器在處理時,會解析出全部交由Spring容器管理的Bean,將它們解析成BeanDefinition,而後放入到BeanFactoryBeanDefinitionMap中。
  • 該方法最終會調用到PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法,主要做用是執行全部BeanFactoryPostProcessorpostProcessorBeanFactory()方法。BeanFactoryPostProcessor又分爲兩種狀況,一種是直接實現BeanFactoryPostProcessor接口的類,另外一種狀況是實現了BeanDefinitionRegistryPostProcessor接口(BeanDefinitionRegistryPostProcessor繼承了BeanFactoryPostProcessor接口)。
    UML圖
  • 在執行過程當中先執行全部的BeanDefinitionRegistryPostProcessorpostProcessorBeanDefinitionRegistry()方法,而後再執行BeanFacotryPostProcessorpostProcessorBeanFactory()方法。
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,ConfigurationClassPostProcessorUML圖如上(刪減了部分不重要的繼承關係)
6.2 registerBeanPostProcessors()
  • 該方法的做用是找到全部的BeanPostProcessor,而後將這些BeanPostProcessor實例化(會調用getBean()方法,getBean()方法的主要邏輯是,若是bean存在於BeanFactory中,則返回bean;若是不存在,則會去建立。在後面會仔細分析getBean()的執行邏輯)。將這些PostProcessor實例化後,最後放入到BeanFactorybeanPostProcessors屬性中。
  • 問題:如何找到全部的BeanPostProcessor? 包括Spring內置的和開發人員自定義的。
  • 因爲在refresh()方法中,會先執行完invokeBeanFactoryPostProcessor()方法,這樣全部自定義的BeanPostProcessor類均已經被掃描出並解析成BeanDefinition(掃描和解析又是誰作的呢?ConfigurationClassPostProcessor作的),存入至BeanFactoryBeanDefinitionMap,因此這兒能經過方法以下一行代碼找出全部的BeanPostProcessor,而後經過getBean()所有實例化,最後再將實例化後的對象加入到BeanFactorybeanPostProcessors屬性中,該屬性是一個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接口。
6.3 initMessageSource()
  • 用來支持消息國際化,如今通常項目中不會用到國際化相關的知識。
6.4 initApplicationEventMulticaster()

該方法初始化了一個事件廣播器,若是容器中存在了beanNameapplicationEventMulticaster的廣播器,則使用該廣播器;若是沒有,則初始化一個SimpleApplicationEventMulticaster。該事件廣播器是用來作應用事件分發的,這個類會持有全部的事件監聽器(ApplicationListener),當有ApplicationEvent事件發佈時,該事件監聽器能根據事件類型,檢索到對該事件感興趣的ApplicationListenergithub

  • 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);
	}
}
複製代碼
6.5 onRefresh()

執行其餘的初始化操做,例如和SpringMVC整合時,須要初始化一些其餘的bean,可是對於純Spring工程來講,onRefresh()方法是一個空方法。spring

6.6 registerListeners()

這一步會將自定義的listenerbean名稱放入到事件廣播器中,同時還會將早期的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);
		}
	}
}
複製代碼
6.7 finishBeanFactoryInitialization()

該方法十分重要,它完成了全部非懶加載的單例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();
}
複製代碼
6.7.1 preInstantiateSingletons()方法
  • 該方法會先判斷bean是不是一個FactoryBean,以及是否當即實例化FactoryBeangetObject()返回的對象,但最終均是調用getBean()方法去實例化對象。在Bean實例化、初始化完成後,會判斷Bean是否實現了SmartSingletonInitializing接口,若是實現了,則會調用該接口的afterSingletonInstantiated()方法。
  • Tips:這裏提到了FactoryBean,不是BeanFactory。這二者名字很像,但做用倒是天差地別,有興趣的朋友能夠先本身Google查下相關知識。這裏先簡單介紹一下,後續會單獨寫一篇文章介紹FactoryBean,並經過FactoryBean去解析SpringMyBatis整合的原理。
  • 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()方法流程圖
  • 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
6.7.2 getBean()
  • getBean()方法會調用doGetBean()方法。
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}
複製代碼
6.7.3 doGetBean()
  • 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;若不是以&符號開頭,則會返回FactoryBeangetObject()方法的返回值對象。
  • 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;
}
複製代碼
6.7.4 createBean()
  • doGetBean()最終會調用createBean()來建立bean
  • createBean()方法的代碼中,主要有兩行核心代碼:
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
複製代碼
  • resolveBeforeInstantiation()方法在bean實例化以前調用,在這個方法中執行了後置處理器InstantiationAwareBeanPostProcessorpostProcessBeforeInstantiation()方法,在bean實例化以前對bean進行處理。這個擴展點的意義十分重大,SpringAOP就是在這兒實現的,感興趣的朋友可閱讀AnnotationAwareAspectJAutoProxyCreator這個類的源碼,後續會單獨寫一篇文章進行分析。
  • 若是resolveBeforeInstantiation()的返回值不爲null,則直接將結果返回。若是爲null,則會繼續執行方法doCreateBean()。在doCreateBean()方法中,進行了Bean的實例化、屬性賦值、初始化等操做。
  • createBean()方法的流程圖
    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);
	}
}
複製代碼
6.7.5 doCreateBean()
  • 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等註解實現自動裝配。這一步的表明後置處理器有AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor是用來處理Spring提供的註解和JSR-330中的部分註解,如:@Autowired@Value@InjectCommonAnnotationBeanPostProcessor是用來處理JSR-250中的註解,如@Resource@PostConstruct@PreDestroy編程

  • 接下來會將半成品的bean(由於此時還未給bean的屬性賦值,未完成自動裝配,所以稱之爲半成品)放入到DefaultSingletonBeanRegistry類的singletonFactories的屬性中,singletonFactories屬性是一個MapkeybeanName,值爲ObjectFactory類型(實際上就是一個lambda表達式),當調用ObjectFactorygetObject()方法時,會執行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()方法,這一步的主角就是AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostBeanPostProcessor了,它們會根據前面緩存在injectionMetadataCache中的註解信息來進行自動裝配。
  • 在執行完populateBean()方法後後,接下來回執行initializeBean()方法,即進入初始化階段。在initializeBean()方法中,最早執行invokeAwareMethods()方法,即執行Aware接口的方法,如:BeanNameAwareBeanClassLoaderAwareBeanFactoryAware。而後再一次執行全部Bean後置處理器的BeanPostProcessor.postProcessBeforeInitialization()方法。接着執行invokeInitMethods()方法,在invokeInitMethods()方法中,會執行InitializingBeanafterPropertiesSet()方法,和定義bean時自定義的initMethod()方法。最後再一次執行bean後置處理器,BeanPostProcessor.postProcessAfterInitialization()
  • 至此bean的實例化、初始化過程已經完成,建立好的bean會被返回,如果單例bean,最後會被存放到DefaultSingletonBeanRegistrysingletonObjects中。
6.8 finishRefresh()
  • 執行到這一步,Spring容器的啓動基本結束了,此時Bean已經被實例化完成,且完成了自動裝配。執行finishRefresh()方法,是爲了在容器refresh()結束時,作一些其餘的操做,例如:發佈ContextRefreshedEvent事件,這樣當咱們想在容器refresh完成後執行一些特殊的邏輯,就能夠經過監聽ContextRefreshedEvent事件來實現。Spring內置了四個和應用上下文(ApplicationContextEvent)有關的事件:ContextRefreshedEventContextStartedEventContextStopedEventContextClosedEvent
protected void finishRefresh() {
    clearResourceCaches();
    initLifecycleProcessor();
    getLifecycleProcessor().onRefresh();
    // 發佈ContextRefreshedEvent
    publishEvent(new ContextRefreshedEvent(this));
    LiveBeansView.registerApplicationContext(this˛);
}
複製代碼
6.9 resetCommonCaches()

最後在refresh()方法的finally語句塊中,執行了resetCommonCaches()方法。由於在前面建立bean時,對單例bean的元數據信息進行了緩存,而單例bean在容器啓動後,不會再進行建立了,所以這些緩存的信息已經沒有任何用處了,在這裏進行清空,釋放部份內存。數組

protected void resetCommonCaches() {
    ReflectionUtils.clearCache();
    AnnotationUtils.clearCache();
    ResolvableType.clearCache();
    CachedIntrospectionResults.clearClassLoader(getClassLoader());
}
複製代碼

7. Bean生命週期

  • 從上面Spring的源碼分析中,能夠看出,啓動過程當中,bean的建立過程最爲複雜,在建立過程當中,先後一共出現了8次調用BeanPostPorcessor(實際上在bean的整個生命週期中,一共會出現9次調用後置處理器,第九次出如今bean的銷燬階段。)
  • 結合Spring的源碼,單例bean的生命週期能夠總結爲以下一張圖
    Bean生命週期圖

8. 總結

  • 本文介紹了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的建立過程當中,一共出現了8BeanPostProcessor的執行,在這些後置處理器的執行過程當中,完成了AOP的實現、bean的自動裝配、屬性賦值等操做。
  • 最後經過一張流程圖,總結了Spring中單例Bean的生命週期。

9. 計劃

本文主要介紹了Spring的啓動流程,但對於一些地方的具體實現細節沒有展開分析,所以後續Spring源碼分析的計劃以下:緩存

  • ConfigurationClassPostProcessor類如何掃描包,解析配置類。
  • @Import註解做用與@Enable系列註解的實現原理
  • JDK動態代理與CGLIB代理
  • FactoryBean的用途和源碼分析
  • AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor如何實現自動裝配,Spring如何解決循環依賴
  • AOP的實現原理
  • SpringBoot源碼分析

10. 推薦性能監控工具

  • 最後推薦一款開源的性能監控工具——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,也歡迎你們參與開發,謝謝:)微信


歡迎掃描下方二維碼,關注微信公衆號:菜鳥飛呀飛 閱讀更多源碼,再也不面向搜索引擎編程

微信公衆號:菜鳥飛呀飛
相關文章
相關標籤/搜索