AnnotationConfigApplicationContext

核心类,BeanDefinition注册器,所有的BeanDefinition都是调用这个类去注册。

1.registerAnnotationConfigProcessors()

注册后面用到的组件包括:

  • 1.ConfigurationClassPostProcessor 中主要解析注解了@Configuration的类,并对其类上的其他注解解析

  • 2.AutowiredAnnotationBeanPostProcessor @Autowired和@Value的依赖注入

  • 3.RequiredAnnotationBeanPostProcessor 对注解了@Required的setter方法进行校验,setter方法的值必须填充否则抛出BeanInitializationException异常

  • 4.CommonAnnotationBeanPostProcessor对注解了@PostConstruct,@PreDestroy,@Resource等Java自带注解的类的解析并执行

1.注册ConfigurationClassPostProcessor组件

ConfigurationClassPostProcessor 中主要解析注解了@Configuration的类,并对其类上的其他注解解析

2.注册AutowiredAnnotationBeanPostProcessor组件

AutowiredAnnotationBeanPostProcessor @Autowired和@Value的依赖注入

3.注册RequiredAnnotationBeanPostProcessor组件

RequiredAnnotationBeanPostProcessor 对注解了@Required的setter方法进行校验,setter方法的值必须填充否则抛出BeanInitializationException异常

4.注册CommonAnnotationBeanPostProcessor组件

CommonAnnotationBeanPostProcessor对注解了@PostConstruct,@PreDestroy,@Resource等Java自带注解的类的解析并执行

2.refresh()

初始化容器的方法

1.prepareRefresh()

创建环境变量,环境变量作用可以利用@Profile来指定开发环境

2.obtainFreshBeanFactor()

获取BeanFactory,BeanFactory真正实现BeanDefinition的注册器,AnnotationConfigApplicationContext都是委托BeanDefinition去处理的。

3.prepareBeanFactory()

主要功能给beanFactory注册一些组件

    1. 为beanFactory设置ClassLoader。
  • 2.注册EL表达式解析组件。

  • 3.注册ApplicationContextAwareProcessor组件,此组件的作用是对于实现了Aware的接口的bean注入参数,支持EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware。

  • 4.调用ignoreDependencyInterface方法忽略注入ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware,EnvironmentAware时的@Required注解的强制校验

  • 5.注册BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext,作用是生成bean后注入bean用。

  • 6.注册Environment,systemProperties(map),systemEnvironment(map),作用是生成bean后利用名称注入bean用。

4.postProcessBeanFactory()

功能跟prepareBeanFactory一样,部分ApplicationContext会对其扩展。

5.invokeBeanFactoryPostProcessors()

获取所有的扩展BeanDefinitionRegistryPostProcessor或BeanFactoryPostProcessor的bean并创建及初始化,然后调用其方法将BeanDefinitionRegistry或ConfigurableListableBeanFactory设置进去。

6.registerBeanPostProcessors()

主要作用将BeanPostProcessor注册到BeanFactory,BeanPostProcessor的作用,就是对已经创建的bean对象做初始化前和初始化后的修改。

  • 1.添加BeanPostProcessorChecker到BeanPostProcessor容器,其作用就是打印一个警告日志,其警告内容就是在所有BeanPostProcessor还没被初始化完全之前,有的bean已经初始化了并未被之后之后初始化的BeanPostProcessor所捕获。测试了下这种情况会发生在实现BeanPostProcessor的bean引用其他bean。

  • 2.获取用户的BeanPostProcessor并添加到BeanPostProcessor容器。

  • 3.加到ApplicationListenerDetectorr到BeanPostProcessor容器,其作用就是将未被registerListeners()步骤忽略的懒加载的添加ApplicationListener到ApplicationEventMulticaster里。

7.initMessageSource()

主要作用是初始化MessageSource,MessageSource功能就是国际化。

  • 1.如果用户配置的bean中有name为"messageSource"的MessageSource类型的bean,则创建初始化并作为ApplicationContext主MessageSource

  • 2.如果用户没配置则创建一个空的MessageSource

8.initApplicationEventMulticaster()

初始化ApplicationEventMulticaster,ApplicationEventMulticaster里存的是ApplicationListener的集合,ApplicationListener后续流程会添加。

    1. 如果用户配置的bean中有name为"applicationEventMulticaster"的ApplicationEventMulticaster类型的bean。
  • 2.如果用户没配置则创建一个SimpleApplicationEventMulticaster。

9.onRefresh()

扩展点方法,特定的ApplicationContext初始化其他特殊bean

10.registerListeners()

主要功能是添加ApplicationListener到ApplicationEventMulticaster里。

  • 1.用户指定的ApplicationListener

  • 2.查找非懒加载的ApplicationListener的bean的name,添加到ApplicationEventMulticaster。这里的只是获取了ApplicationListener的name,实际上还是未被创建的。这里的查找非懒加载的bean其实未生效,需要将总开关allowEagerClassLoading开启。

11.finishBeanFactoryInitialization()

主要作用是对还未被创建及初始化的非lazy加载的bean进行初始化。

  • 1.初始化ConversionService类型的bean,ConversionService是类型转化工具。

  • 2.初始化LoadTimeWeaverAware,初始化自定义的LoadTimeWeaverAware

  • 3.设置tempClassLoader为空,tempClassLoader是开启LoadTimeWeaver才会设置,其作用是是加载class类改变原先的双亲委派模式,使其加载其镜像class,这样保证LoadTimeWeaver的织入功能在开启前也能进行对class的类型判断等操作,在织入后也能保证捕获到真正的class类的加载。

  • 4.冻结beanDefinition,其作用是在或调用getBeanNamesForType获取beanName时优先走缓存,且所有的beanName都固定且不期待被修改。

  • 5.创建及初始化的非lazy加载的bean进行初始化

12.finishRefresh()

主要功能是触发对应的事件

  • 1.初始化生命周期处理器,LifecycleProcessor。

  • 2.触发生命周期开始事件,即lifecycle的start事件。

  • 3.发送刷新事件,即触发所有ApplicationListener的刷新事件。

  • 4.如果配置了MBean,这注册到MBeanServer,MBeanServer是暴雷接口的方法,可以通过jmx协议查看和调用,这里主要是暴露了ApplicationContext的注册信息供开发者查看。

附图

Spring源码分析之容器初始化-LMLPHP

05-06 16:03