创建IOC容器
创建IOC容器主要流程如下:
- 从META-INF/spring.factories中找到key为org.springframework.boot.ApplicationContextFactory的IOC容器工厂列表。
- 通过工厂方法模式创建IOC容器(AnnotationConfigServletWebServerApplicationContext/AnnotationConfigReactiveWebServerApplicationContext/AnnotationConfigApplicationContext)。
- 在实例化IOC容器时,实例化了基于注解的bean元数据读取器(AnnotatedBeanDefinitionReader)和bean元数据扫描器(ClassPathBeanDefinitionScanner)。
实例化AnnotatedBeanDefinitionReader
- 设置bean注册器registry为当前的IOC容器,如AnnotationConfigServletWebServerApplicationContext。
- 设置条件鉴别器conditionEvaluator,用于在手动注册bean(如SpringApplication实例化时设置的主要配置源primarySources)时进行条件判断。
- 获取IOC容器ApplicationContext中的beanFactory,设置排序器dependencyComparator(用于对BeanFactoryPostProcessor列表、同类型的Spring Bean列表等进行排序)为 AnnotationAwareOrderComparator,设置自动装配候选者解析器autowireCandidateResolver(检查指定bean的bean元数据中autowireCandidate属性是否为true来决定是否将该bean自动装配到其它bean中)为ContextAnnotationAutowireCandidateResolver。
- 将bean工厂后置处理器ConfigurationClassPostProcessor和EventListenerMethodProcessor对应的RootBeanDefinition注册到内存镜像beanDefinitionMap中。
- 将bean后置处理器AutowiredAnnotationBeanPostProcessor对应的RootBeanDefinition注册到内存镜像beanDefinitionMap中。
- 可选性地将bean后置处理器CommonAnnotationBeanPostProcessor和PersistenceAnnotationBeanPostProcessor注册到内存镜像beanDefinitionMap中。
- 将事件监听器工厂DefaultEventListenerFactory对应的RootBeanDefinition注册到内存镜像beanDefinitionMap中。
实例化ClassPathBeanDefinitionScanner
- 设置bean注册器registry为当前的IOC容器,如AnnotationConfigServletWebServerApplicationContext。
- 添加三个AnnotationTypeFilter到includeFilters(用于判断待扫描的类是否匹配)中,这三个Filter分别用于扫描@Component/@Controller/@Service/@Repository、@ManagedBean、@Named注解。
- 设置environment(如StandardServletEnvironment)。
- 策略模式设置resourcePatternResolver为当前ioc容器实例。
- 设置元数据读取器工厂为CachingMetadataReaderFactory。
- 设置componentsIndex。从META-INF/spring.components文件中加载数据放到本地缓存中。
使用componentsIndex是为了让扫描器直接读取静态候选列表,不用扫描,提高效率。使用时,引入spring-context-indexer依赖包,编译或时会自动生成META-INF/spring-components文件。
比如文件格式:
org.example.ApplicationRunner=org.springframework.stereotype.Component,org.springframework.boot.SpringBootConfiguration
org.example.controller.HelloController=org.springframework.stereotype.Component
缓存格式类似:
{
"org.springframework.stereotype.Component":("org.example.ApplicationRunner","org.example"),
"org.springframework.boot.SpringBootConfiguration":("org.example.ApplicationRunner","org.example"),
"org.springframework.stereotype.Component":("org.example.controller.HelloController","org.example.controller")
}
配置IOC容器
- 配置环境
- 设置AbstractApplicationContext中的environment变量。
- 重新设置AnnotatedBeanDefinitionReader中的条件鉴别器conditionEvaluator,用于在手动注册bean(如SpringApplication实例化时设置的主要配置源primarySources)时进行条件判断。
- 重新设置扫描器ClassPathBeanDefinitionScanner中的environment。
- 后置处理ApplicationContext
- 如果指定了bean名称生成器BeanNameGenerator,将其注册成名为 org.springframework.context.annotation.internalConfigurationBeanNameGenerator的bean。
- 如果指定了资源加载器resourceLoader,设置资源加载器resourceLoader和类加载器classLoader。
- 将配置环境时指定的类型转换器ApplicationConversionService设置到applicationContext内置的beanFactory中。
- 初始化ApplicationContext。使用从META-INF/spring.factories中加载的ApplicationContextInitializer列表对applicationContext进行初始化。比如spring-boot.jar中的初始化器如下:
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
- 广播ApplicationContextInitializedEvent事件
- 广播BootstrapContextClosedEvent事件
- 注册参数bean springApplicationArguments和banner bean springBootBanner
- 设置beanFactory属性:允许循环引用allowCircularReferences和运行bean元数据覆盖allowBeanDefinitionOverriding。
- 设置bean工厂后置处理器
- 如果指定lazyInitialization为true,添加bean工厂后置处理器LazyInitializationBeanFactoryPostProcessor。
- 添加用于对外部资源进行排序的bean工厂后置处理器PropertySourceOrderingBeanFactoryPostProcessor。
- 加载主配置源
- 创建bean元数据加载器BeanDefinitionLoader,并设置属性信息
- 加载配置源成beanDefinition。根据配置源类型,可选择使用AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner、XmlBeanDefinitionReader及GroovyBeanDefinitionReader 4种读取器。
- 广播ApplicationPreparedEvent事件。 监听ApplicationPreparedEvent事件的监听器有: EnvironmentPostProcessorApplicationListener、LoggingApplicationListener、 ApplicationPidFileWriter等。