3.1.1_Spring如何加载和解析@Configuration标签
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: