Spring加载流程

2020-09-21  本文已影响0人  ruisheng

参考链接:

https://www.yuque.com/snakes/ayqnq6/fyfefu
https://blog.csdn.net/tzs_1041218129/article/details/107587706
https://juejin.im/post/6869407787760222221

Spring加载流程

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
ac.register(AppConfig.class);
//可以注册普通的bean
//ac.register(User.class);
ac.refresh();
ac.getBean(X.class);
@Configuration
@ComponentScan("com.ruisheng")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig {
}

初始化 AnnotatedBeanDefinitionReader

作用:

  1. 读取spring内部的 唯一的beanFactoryPostProcess 和 5个beanPostProcess。
    • ConfigurationClassPostProcessor (Spring内部唯一的beanFactoryPostProcess的实现类)
    • AutowiredAnnotationBeanPostProcessor
    • CommonAnnotationBeanPostProcessor
    • PersistenceAnnotationBeanPostProcessor
    • EventListenerMethodProcessor
    • DefaultEventListenerFactory
  2. 提供给程序员注册bd(ac.register(AppConfig.class);),一般是用来注册加了@Configuration的类。

源码解析:

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
   Assert.notNull(environment, "Environment must not be null");
   this.registry = registry;
   this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
   //使用注解配置时需要注入的一些后置处理器
   AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

初始化 ClassPathBeanDefinitionScanner

作用:

  1. 程序员能够在外部调用doScan(), 或者 继承该类可以重写scan规则用来动态扫描注解,需要注册到容器。
  2. spring内部是自己重新new 新的对象来扫描。

主要方法:org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan
(扫描basePackage路径下的文件,把符合条件的类,转成bd。)

执行 register(AppConfig.class)

作用:一般是配置类 AppConfig.class,也可以是普通的bean,ac.register(User.class);

主要代码:org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean
(解析bean封装为 BeanDefinitionHolder ,注册到 register 中)

执行 refresh()

prepareRefresh();

准备工作包括设置启动时间,是否激活标志位。

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

返回一个factory(DefaultListableBeanFactory)

prepareBeanFactory(beanFactory);

准备工厂

postProcessBeanFactory(beanFactory);

invokeBeanFactoryPostProcessors(beanFactory);

作用:

  1. 主要就是扫描包得到类
  2. 通过匹配规则和排除规则得到合适的类
  3. 再通过解析这些类,比如配置类去获取所有的解析出来的类
  4. 将这些扫描解析出来的类,变成bd

源码分析:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   /**
    * getBeanFactoryPostProcessors()得到 1.自定义的且没加@Compoment、2.spring内部维护的BeanDefinitionRegistryPostProcessor实现类。
    * 1.自定义的并且没加@Compoment注解的BeanFactoryPostProcessors实现类。
    * (就是程序员自己写的,并且没有交给spring管理,就是没有加上@Component)
    *  (这里所谓自定义指手动调用:annotationConfigApplicationContext.addBeanFactoryPostProcessor();)
    * 2.得到spring内部的 BeanDefinitionRegistryPostProcessor 实现类
    *   spring内部只有一个实现类:ConfigurationClassPostProcessor
   */
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

   // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
   // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}
  1. 执行 BeanDefinitionRegistryPostProcessor

    1. postProcessBeanDefinitionRegistry(registry) 由程序员add的

    2. postProcessBeanDefinitionRegistry(registry) 有特色(比如排序,优先级等等) 由spring内部和程序员(register,注解)

      备注:这里spring内部的有 ConfigurationClassPostProcessor。

    3. postProcessBeanDefinitionRegistry(registry) 剩余的子类 由spring内部和程序员(register,注解)

    4. 所有父方法 postProcessBeanFactory(beanFactory)

  2. 执行 BeanFactoryPostProcessors

    1. postProcessBeanFactory(beanFactory) 由程序员add的
    2. postProcessBeanFactory(beanFactory) 有特色(比如排序,优先级等等) 由spring内部和程序员(register,注解)
    3. postProcessBeanFactory(beanFactory) 剩余的 由spring内部和程序员(register,注解)

备注1:ConfigurationClassPostProcessor 是优先级最高的被执行的processor(实现了PriorityOrdered接口)。
ConfigurationClassPostProcessor 最先被处理的原因:如果程序中有自定义的BeanFactoryPostProcessor,那么这个PostProcessor首先得通过ConfigurationClassPostProcessor被解析出来,然后才能被Spring容器找到并执行。(ConfigurationClassPostProcessor不先执行的话,这个Processor是不会被解析的,不会被解析的话也就不会执行了)。

备注2:在使用mybatis时,一般配置了MapperScannerConfigurer的bean,这个bean就是继承的BeanDefinitionRegistryPostProcessor,所以也是这个地方把扫描的mybatis的接口注册到容器中的。

registerBeanPostProcessors(beanFactory);

注册 BeanPostProcessor 的实现类,即从Spring容器中找出的BeanPostProcessor接口的bean,并设置到BeanFactory的属性中。之后bean被实例化的时候会调用这个BeanPostProcessor。

为什么要在这里注册呢?不能在前面或后面?????????????????

initMessageSource();

初始化国际化资源

onRefresh();

registerListeners();

finishBeanFactoryInitialization(beanFactory);

完成BeanFactory的bean实例化

finishRefresh();

上一篇下一篇

猜你喜欢

热点阅读