创建并配置IOC容器

109 阅读3分钟

创建IOC容器

创建IOC容器主要流程如下:

  1. 从META-INF/spring.factories中找到key为org.springframework.boot.ApplicationContextFactory的IOC容器工厂列表。
  2. 通过工厂方法模式创建IOC容器(AnnotationConfigServletWebServerApplicationContext/AnnotationConfigReactiveWebServerApplicationContext/AnnotationConfigApplicationContext)。
  3. 在实例化IOC容器时,实例化了基于注解的bean元数据读取器(AnnotatedBeanDefinitionReader)和bean元数据扫描器(ClassPathBeanDefinitionScanner)。

实例化AnnotatedBeanDefinitionReader

  1. 设置bean注册器registry为当前的IOC容器,如AnnotationConfigServletWebServerApplicationContext。
  2. 设置条件鉴别器conditionEvaluator,用于在手动注册bean(如SpringApplication实例化时设置的主要配置源primarySources)时进行条件判断。
  3. 获取IOC容器ApplicationContext中的beanFactory,设置排序器dependencyComparator(用于对BeanFactoryPostProcessor列表、同类型的Spring Bean列表等进行排序)为 AnnotationAwareOrderComparator,设置自动装配候选者解析器autowireCandidateResolver(检查指定bean的bean元数据中autowireCandidate属性是否为true来决定是否将该bean自动装配到其它bean中)为ContextAnnotationAutowireCandidateResolver。
  4. 将bean工厂后置处理器ConfigurationClassPostProcessor和EventListenerMethodProcessor对应的RootBeanDefinition注册到内存镜像beanDefinitionMap中。
  5. 将bean后置处理器AutowiredAnnotationBeanPostProcessor对应的RootBeanDefinition注册到内存镜像beanDefinitionMap中。
  6. 可选性地将bean后置处理器CommonAnnotationBeanPostProcessor和PersistenceAnnotationBeanPostProcessor注册到内存镜像beanDefinitionMap中。
  7. 将事件监听器工厂DefaultEventListenerFactory对应的RootBeanDefinition注册到内存镜像beanDefinitionMap中。

实例化ClassPathBeanDefinitionScanner

  1. 设置bean注册器registry为当前的IOC容器,如AnnotationConfigServletWebServerApplicationContext。
  2. 添加三个AnnotationTypeFilter到includeFilters(用于判断待扫描的类是否匹配)中,这三个Filter分别用于扫描@Component/@Controller/@Service/@Repository、@ManagedBean、@Named注解。
  3. 设置environment(如StandardServletEnvironment)。
  4. 策略模式设置resourcePatternResolver为当前ioc容器实例。
  5. 设置元数据读取器工厂为CachingMetadataReaderFactory。
  6. 设置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容器

  1. 配置环境
    • 设置AbstractApplicationContext中的environment变量。
    • 重新设置AnnotatedBeanDefinitionReader中的条件鉴别器conditionEvaluator,用于在手动注册bean(如SpringApplication实例化时设置的主要配置源primarySources)时进行条件判断。
    • 重新设置扫描器ClassPathBeanDefinitionScanner中的environment。
  2. 后置处理ApplicationContext
    • 如果指定了bean名称生成器BeanNameGenerator,将其注册成名为 org.springframework.context.annotation.internalConfigurationBeanNameGenerator的bean。
    • 如果指定了资源加载器resourceLoader,设置资源加载器resourceLoader和类加载器classLoader。
    • 将配置环境时指定的类型转换器ApplicationConversionService设置到applicationContext内置的beanFactory中。
  3. 初始化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
  1. 广播ApplicationContextInitializedEvent事件
  2. 广播BootstrapContextClosedEvent事件
  3. 注册参数bean springApplicationArguments和banner bean springBootBanner
  4. 设置beanFactory属性:允许循环引用allowCircularReferences和运行bean元数据覆盖allowBeanDefinitionOverriding。
  5. 设置bean工厂后置处理器
    • 如果指定lazyInitialization为true,添加bean工厂后置处理器LazyInitializationBeanFactoryPostProcessor。
    • 添加用于对外部资源进行排序的bean工厂后置处理器PropertySourceOrderingBeanFactoryPostProcessor。
  6. 加载主配置源
    • 创建bean元数据加载器BeanDefinitionLoader,并设置属性信息
    • 加载配置源成beanDefinition。根据配置源类型,可选择使用AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner、XmlBeanDefinitionReader及GroovyBeanDefinitionReader 4种读取器。
  7. 广播ApplicationPreparedEvent事件。 监听ApplicationPreparedEvent事件的监听器有: EnvironmentPostProcessorApplicationListener、LoggingApplicationListener、 ApplicationPidFileWriter等。