003-ApplicationContext启动过程详解

121 阅读5分钟

ApplicationContext启动过程详解

public AnnotationConfigApplicationContext(Class<?>... componentClasses) 
1.  //创建BeanFactory
2.  //生成AnnotatedBeanDefinitionReader
3.  //生成ClassPathBeanDefinitionScanner
this();
//  利用reader把componentClasses注册为一个BeanDefinition
register(componentClasses);
调用AbstractApplicationContext的refresh()方法,模板模式,会启动ApplicationContext
为什么叫refresh,而不叫start?
refresh();

this():

// 生成并注册5个BeanDefinition Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);  BeanDefinitionHolder 
// 1.ConfigurationClassPostProcessor //spring自动扫描的时候使用的,实现了BeanDefinitionRegistryPostProcessor->BeanFactoryPostProcessor->postProcessBeanFactory->BeanFactoryPostProcessor

// 2.AutowiredAnnotationBeanPostProcessor //spring中的注解@Autowired 的Bean的处理 是一个BeanPostProcessor

// 3.CommonAnnotationBeanPostProcessor //javax.annotation.PostConstruct在这里处理的,@Resource,@WebServiceRef,是一个BeanPostProcessor

// 4.EventListenerMethodProcessor//是一个BeanPostProcessor  Registers {@link EventListener} methods as individual(个人) {@link ApplicationListener} instances.Implements {@link BeanFactoryPostProcessor} (as of 5.1) primarily(主要用于早期检索) for early retrieval,avoiding AOP checks for this processor bean and its {@link EventListenerFactory} delegates.


// 5.DefaultEventListenerFactory 注册DefaultEventListenerFactory类型的BeanDefinition
this.reader = new AnnotatedBeanDefinitionReader(this);

register(componentClasses);

// 利用reader把AppConfig.class注册为一个BeanDefinition,获取该类上的相关注解等。 register(componentClasses);

refresh();

  • ApplicationContext关闭之后不代表JVM也关闭了,ApplicationContext是属于JVM的,说白了ApplicationContext也是JVM中的一个对象。
  • AbstractRefreshableApplicationContext extends AbstractApplicationContext 可以刷新
  • GenericApplicationContext extends AbstractApplicationContext 不可以刷新
  • Load or refresh the persistent representation of the configuration,//持久化配置 which might an XML file, properties file, or relational database schema.As this is a startup method, it should destroy already created singletons if it fails, to avoid dangling resources. In other words, after invocation of that method, either all or no singletons at all should be instantiated. @throws BeansException if the bean factory could not be initialized @throws IllegalStateException if already initialized and multiple refreshattempts are not supported
  1. prepareRefresh(): a. 记录启动时间 b. 可以允许子容器设置一些内容到Environment中 c. 验证Environment中是否包括了必须要有的属性

  2. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 进行BeanFactory的refresh,在这里会去调用子类的refreshBeanFactory方法,具体子类是怎么刷新的得看子类,然后再调用子类的getBeanFactory方法,重新得到一个BeanFactory

  3. prepareBeanFactory(beanFactory);

    • 添加忽略set方法的ignoredDependencyInterface:可以向这个属性中添加一些接口,如果某个类实现了这个接口,并且这个类中的某些set方法在接口中也存在,那么这个set方法在自动注入的时候是不会执行的,比如EnvironmentAware这个接口,如果某个类实现了这个接口,那么就必须实现它的setEnvironment方法,而这是一个set方法,和Spring中的autowire是冲突的,那么Spring在自动注入时是不会调用setEnvironment方法的,而是等到回调Aware接口时再来调用(注意,这个功能仅限于xml的autowire,@Autowired注解是忽略这个属性的) beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); //另外其实在构造BeanFactory的时候就已经提前添加了另外三个:DefaultListableBeanFactory ignoreDependencyInterface(BeanNameAware.class); ignoreDependencyInterface(BeanFactoryAware.class); ignoreDependencyInterface(BeanClassLoaderAware.class);

    • 添加resolvableDependencies:在byType进行依赖注入时,会先从这个属性中根据类型找bean。直接把ApplicationContext对象放入Bean工厂中,当getBean(type)时,如果type就是这四个type,则直接返回所设置的实例 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); //当前BeanFactory对象 beanFactory.registerResolvableDependency(ResourceLoader.class, this);//当前ApplicationContext对象 beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);//当前ApplicationContext对象 beanFactory.registerResolvableDependency(ApplicationContext.class, this);//当前ApplicationContext对象

    • 添加一个Bean的后置处理器:ApplicationListenerDetector,是一个BeanPostProcessor,用来判断某个Bean是不是ApplicationListener,如果是则把这个Bean添加到ApplicationContext中去,注意一个ApplicationListener只能是单例的 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    • 添加一个Bean的后置处理器:LoadTimeWeaverAwareProcessor,是一个BeanPostProcessor,用来判断某个Bean是不是实现了LoadTimeWeaverAware接口,如果实现了则把ApplicationContext中的loadTimeWeaver回调setLoadTimeWeaver方法设置给该Bean。 添加一些单例bean到单例池: "environment":Environment对象 "systemProperties":System.getProperties()返回的Map对象 "systemEnvironment":System.getenv()返回的Map对象

  4. postProcessBeanFactory(beanFactory); // 子类可以对BeanFactory进行进一步初始化

  5. invokeBeanFactoryPostProcessors(beanFactory);//执行BeanFactoryPostProcessor 默认情况下:

    • 此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition

    • 而这6个中只有一个BeanFactoryPostProcessor&BeanDefinitionRegistryPostProcessor:ConfigurationClassPostProcessor

    • 这里会执行ConfigurationClassPostProcessor进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中

    • 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行。

    • 第一阶段registryProcessor.postProcessBeanDefinitionRegistry(registry);此时在BeanFactory中会存在一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor,它也是一个BeanDefinitionRegistryPostProcessor 从BeanFactory中找到类型为BeanDefinitionRegistryPostProcessor的beanName,也就是ConfigurationClassPostProcessor, 然后调用BeanFactory的getBean方法得到实例对象。 执行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()方法:

      • 解析AppConfig类扫描得到BeanDefinition并注册
      • 解析@Import,@Bean等注解得到BeanDefinition并注册
      • 在这里,我们只需要知道在这一步会去得到BeanDefinition,而这些BeanDefinition中可能存在BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor,所以执行完ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()方法后,还需要继续执行其他BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
      • 执行其他BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
      • 执行所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法
    • 第二阶段

      • 从BeanFactory中找到类型为BeanFactoryPostProcessor的beanName,而这些BeanFactoryPostProcessor包括了上面的BeanDefinitionRegistryPostProcessor
      • 执行还没有执行过的BeanFactoryPostProcessor的postProcessBeanFactory()方法 所有的BeanFactoryPostProcessor的逻辑都执行完了,主要做的事情就是得到BeanDefinition并注册到BeanFactory中
  6. registerBeanPostProcessors(beanFactory);

    • // 从BeanFactory找出扫描得到得BeanPostProcessor,实例化并注册到BeanFactory中。
  7. registerBeanPostProcessors(beanFactory):自己定义了一些BeanPostProcessor,在这一步就会把BeanFactory中所有的BeanPostProcessor找出来并实例化得到一个对象,并添加到BeanFactory中去(属性beanPostProcessors)最后再把ApplicationListenerDetector移动到最后)

  8. initMessageSource()//这样ApplicationContext就可以使用国际化的功能了,BeanFactory是否有messageSource这个BD.

  9. initApplicationEventMulticaster();让ApplicationContext拥有事件发布的功能

  10. onRefresh();//执行子类的onRefresh方法,目前没用

  11. registerListeners(); applicationEventMulticaster中添加ApplicationListener类型的beanName

  12. finishBeanFactoryInitialization(beanFactory):完成BeanFactory的初始化,主要就是实例化非懒加载的单例Bean

  13. finishRefresh(): 发布事件,BeanFactory的初始化完后,就到了Spring启动的最后一步了

    • 设置ApplicationContext的lifecycleProcessor,默认情况下设置的是DefaultLifecycleProcessor
    • 调用lifecycleProcessor的onRefresh()方法,如果是DefaultLifecycleProcessor,那么会获取所有类型为Lifecycle的Bean对象,然后调用它的start()方法,这就是ApplicationContext的生命周期扩展机制
    • 发布ContextRefreshedEvent事件
  14. 总结