Spring有一個內部的BeanFactoryPostProcessor
ID:org.springframework.context.annotation.internalConfigurationAnnotationProcessor;
類型:BeanDefinitionRegistryPostProcessor;
實現類ConfigurationClassPostProcessor;
負責解析處理所有@Configuration標簽類,並將Bean定義注冊到BeanFactory中。
那ConfigurationClassPostProcessor是怎么處理打了@Configuration標簽的Class的呢?
首先進行解析過程是在ApplicationContext-refresh-invokeBeanFactoryPostProcessor中執行的。
此時的BeanFactory中已經將加載了main class,以及內部定義的class。內部定義的class都是帶internal的,這些並不是Configuration Class,解析程序會忽略這些類,最后只有sampleApplication會進行Configuration的解析處理。此時BeanFactory中的Bean定義請見附1。
ConfigurationClassPostProcessor的解析過程:
ConfigurationClassPostProcessor通過ConfigurationClassParser進行實際解析操作。
ConfigurationClassParser將會進行如下解析處理:
處理嵌套的MemberClass
處理@PropertySource標簽,用來解析屬性文件並設置到Environment中。
處理@ComponentScan標簽,掃描package下的所有Class並進行迭代解析。
處理@Import標簽。
處理@ImportResource標簽。
處理@Bean標簽。
處理所有繼承的Interface上的@Bean標簽。
處理SuperClass。
處理標簽中的DeferredImport。
DeferredImport跟spring-boot-autoconfig息息相關。
在@SpringBootApplication中有@EnableAutoConfiguration,@EnableAutoConfiguration中有@Import(AutoConfigurationImportSelector.class),AutoConfigurationImportSelector是DeferredImportSelector,會被作為DeferredImport進行處理。
那DeferredImportSelector都做了些什么呢?
1、加載spring-boot-autoconfig包下的spring-autoconfigure-metadata.properties配置文件,獲取所有支持自動配置的信息。
2、獲取所有支持EnableAutoConfiguration的組件信息,這部分信息配置在spring-boot-autoconfig包下的spring.factories下,可以看到支持127個第三方組件配置。
3、對現有的這些組件進行排序、去重等處理。
4、然后使用AutoConfigurationImportFilter進行過濾,過濾的方式基本上是判斷現有系統是否引入了某個組件,(系統是否使用哪個組件是在pom定義的時候就確定了的),如果有的話則進行相關配置。比如ServletWebServerFactoryAutoConfiguration,會在ServletRequest.class等條件存在的情況下進行配置,而EmbeddedTomcat會在Servlet.class, Tomcat.class存在的情況下創建TomcatServletWebServerFactory。
最后有效的DeferredImport請見附2,共有22個配置類。
而在DeferredImport之后BeanFactory中的Beans則有112個,里邊有我們自定義的sampleApplication、sampleController,以及組件自定義的dispatcherServlet等。這樣整個web工程啟動所需要的Bean基本上都全了。
附1:
name:org.springframework.context.annotation.internalConfigurationAnnotationProcessor,
class:rg.springframework.context.annotation.ConfigurationClassPostProcessor
name:org.springframework.context.annotation.internalAutowiredAnnotationProcessor,
class:org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
name:org.springframework.context.annotation.internalRequiredAnnotationProcessor,
class:org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor
name:org.springframework.context.annotation.internalCommonAnnotationProcessor,
class:org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
name:org.springframework.context.event.internalEventListenerProcessor,
class:org.springframework.context.event.EventListenerMethodProcessor
org.springframework.context.event.internalEventListenerFactory,
class:org.springframework.context.event.DefaultEventListenerFactory
name:sampleApplication,
class:com.travelsky.ibeplus.sample.helloworld.SampleApplication
name:org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory
class:org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer$SharedMetadataReaderFactoryBean
附2:
附3: