美文网首页Spring Java 核心技术Spring
Spring源码启动过程以及拓展点

Spring源码启动过程以及拓展点

作者: 蓝梅 | 来源:发表于2022-04-11 00:35 被阅读0次

容器启动过程

  1. 第一步先调用this();构造方法,这时父类构造器会初始化容器的 beanFactory 属性,属性为DefaultListableBeanFactory,带有存储BeanDefinition 和单例 bean 的功能
  • 新建一个注解Bean定义读取器 new AnnotatedBeanDefinitionReader(this); 这个读取器主要是初始化环境变量,以及注册 一些创世纪的 BeanDefinition 【例如:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、EventListenerMethodProcessor、DefaultEventListenerFactory】
  • 新建一个类路径扫描器ClassPathBeanDefinitionScanner
  1. 容器调用register(componentClasses);把启动类注册成BeanDefinition放入到容器中
  2. 启动Spring,调用 refresh() 方法去刷新容器
  3. prepareRefresh() 准备刷新方法,没有做什么重要的事情,主要是设置了下容器的启动状态
  4. 调用obtainFreshBeanFactory();获取到容器的工厂,DefaultListableBeanFactory
  5. 调用prepareBeanFactory(beanFactory)
  • 设置容器的类加载器
  • 设置Spring容器中需要忽略的set方法
  • ResourceEditorRegistrar注册资源编辑器,当Bean初始化的时候,构造器上需要注入Spring资源相关的Bean时,由该类注入
  • 注册三个BeanPostProcessor到容器中【ApplicationContextAwareProcessor (会在Bean初始化前,调用,例如ApplicationContextAware接口,会注入ApplicationContext容器到类中)、LoadTimeWeaverAwareProcessor (织入Bean后置处理器)】
  1. 调用postProcessBeanFactory(beanFactory);留给子类来设置BeanFactory
  2. 调用invokeBeanFactoryPostProcessors(beanFactory) 方法
  • 第一次调用已经初始化过的 BeanDefinitionRegistryPostProcessor 类的 registryProcessor.postProcessBeanDefinitionRegistry(registry) 方法,基本上不会有,除非自己在前面步骤设置过
  • 第二次调用实现了PriorityOrdered的 BeanDefinitionRegistryPostProcessor 接口的类的.postProcessBeanDefinitionRegistry(registry) 方法,一般只会有 ConfigurationClassPostProcessor 类,这个类在 1.a 步骤中被注册成BeanDefinition
    • ConfigurationClassPostProcessor 去解析配置类,如果类是由 @Configuration 注解的类,则为 full 配置类,其他则为 lite 配置类【full配置类,会生成CGLib动态代理,@Bean方法只会调用一次,下次就直接获取上次的对象;Lite配置类,则生成普通类】
    • 生成Configuration解析器,会去解析 @ComponentScan 注解包下所有的类,并且会循环调用,知道把所有需要解析成 BeanDefinition 的类都注册进来 (包括@Component、@Import、@ImportResource这些注解)
    • 会解析配置类中有多个@Bean
  • 调用实现了 Ordered 的 BeanDefinitionRegistryPostProcessor 接口的类 的 postProcessBeanDefinitionRegistry(registry) 方法
  • 调用没有实现 PriorityOrdered、Ordered 的 BeanDefinitionRegistryPostProcessor 接口的类 的 postProcessBeanDefinitionRegistry(registry) 方法
  • 然后调用之前所有 BeanDefinitionRegistryPostProcessor 类的 postProcessBeanFactory(beanFactory) 方法,会调用 ConfigurationClassPostProcessor 类
    • ConfigurationClassPostProcessor. postProcessBeanFactory(beanFactory) 会把Full配置类的BeanDefinition 的类型设置成CGLIB的动态代理类型,初始化时,就是CGLIB动态代理
  • 调用实现了PriorityOrdered 的 BeanFactoryPostProcessor 类的 postProcessBeanFactory(beanFactory) 方法
  • 调用实现了Ordered 的 BeanFactoryPostProcessor 类的 postProcessBeanFactory(beanFactory) 方法
  • 调用没有实现 PriorityOrdered、Ordered 的 BeanFactoryPostProcessor 类的 postProcessBeanFactory(beanFactory) 方法
    • EventListenerMethodProcessor (会在所有Bean都实例化完成后,解析Bean中是否带有@EventListener方法,如果有,则会利用EventListenerFactory,生成一个ApplicationListener放入容器中)默认实例化出所有 EventListenerFactory 的类
  1. 调用registerBeanPostProcessors(beanFactory);注册Bean的后置处理器到容器中
  • 主要是两个后置处理器 internalAutowiredAnnotationProcessor、internalCommonAnnotationProcessor
  • 会按照优先PriorityOrdered然后Ordered,最后都没实现的BeanPostProcess类的顺序放入到容器中
  • 最后放入ApplicationListenerDetector
  1. 调用 initMessageSource(); 初始化国际化 ,一般是DelegatingMessageSource对象
  2. 调用 initApplicationEventMulticaster(); 设置容器的事件多播器为 SimpleApplicationEventMulticaster
  3. 调用 onRefresh(); 方法,Springboot 就是调用这个方法来启动tomcat容器的
  4. 调用registerListeners();注册事件监听器到容器中,并且如果有早期事件类型,则在容器事件广播器未生成好之前发布事件
  5. 调用 finishBeanFactoryInitialization(beanFactory); 实例化非懒加载的 Bean
  • 先判断是否有conversionService类型的Bean,如果有,则需要转化生成
  • 实例化LoadTimeWeaverAware对象
  • 实例化Bean
    • 实例化之前会先调用 InstantiationAwareBeanPostProcessor 接口的 postProcessBeforeInstantiation 方法,这个时候可以自己初始化出来,返回给容器
    • 实例化对象,这个时候有个策略 getInstantiationStrategy().instantiate(mbd, beanName, this); 如果是之前设置了CGLIB动态代理,这里生成的是代理后的对象
    • 遍历调用MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()方法
      • 这里会调用 AutowiredAnnotationBeanPostProcessor 的 postProcessMergedBeanDefinition 找到所有的 @Autowired或者@Value 注解的方法或属性,为后续IOC,依赖注入做准备
    • 自动注入属性
    • 生成后先遍历所有的 BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName) 方法,这个方法可以重新返回一个新的Bean
      • 所有的 Aware 拓展点在这里实现,通过 ApplicationContextAwareProcessor 类,实现了EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware、ApplicationStartupAware等类在这一步注入
    • 实例化Bean,如果Bean实现了 InitializingBean 接口的Bean,会调用它的 afterPropertiesSet 方法
    • 遍历所有的 BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName) 方法,这个方法可以重新返回一个新的Bean
  • 所有Bean实例化完成后 便利所有bean,调用实现了 SmartInitializingSingleton 接口类的afterSingletonsInstantiated方法
  1. 最后调用 finishRefresh(),发布容器 publishEvent(new ContextRefreshedEvent(this)); 刷新完成事件

Spring所有拓展点以及顺序

  1. 实现了 BeanDefinitionRegistryPostProcessor 接口的类,调用 postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) 方法,可以获取到Bean定义的注册器,去注册BeanDefinition,调用会按照先调用实现了 PriorityOrdered 接口 再调用 Ordered 接口 最后再调用没有实现 PriorityOrdered 接口 、 Ordered 接口 的 BeanDefinitionRegistryPostProcessor 类
  2. 实现了 BeanFactoryPostProcessor 接口的类,调用 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 方法,可以获取到Bean定义的注册器,去注册BeanDefinition,调用会优先调用实现了BeanDefinitionRegistryPostProcessor 接口的类的 postProcessBeanFactory方法,再按照先调用实现了 PriorityOrdered 接口 再调用 Ordered 接口 最后再调用没有实现 PriorityOrdered 接口 、 Ordered 接口 的 BeanDefinitionRegistryPostProcessor 类
  3. 实现了 InstantiationAwareBeanPostProcessor 接口的类,调用 postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 方法,这个方法可以直接自己初始化出来Bean
  4. 实现了 MergedBeanDefinitionPostProcessor 接口的类,调用 postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) 方法;这个时候Bean已经初始化了,但是属性还没有注入;AutowiredAnnotationBeanPostProcessor 的 postProcessMergedBeanDefinition 找到所有的 @Autowired或者@Value 注解的方法或属性,为后续IOC,依赖注入做准备
  5. 实现了EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware、ApplicationStartupAware的类,会在这一步注入相关环境变量属性
  6. 实现了 BeanPostProcessor 接口的类,调用 postProcessBeforeInitialization(Object bean, String beanName) 方法,这一步Bean已经实例化了,并且属性已经注入了,也可以通过这个拓展来修改对象
  7. 实现了 InitializingBean 接口的Bean,会调用对象的 afterSingletonsInstantiated() 方法。一般作为对象初始化完成调用的拓展点
  8. 实现了 BeanPostProcessor 接口的类,调用 postProcessAfterInitialization(Object bean, String beanName) 方法,这一步Bean已经实例化了,并且属性已经注入了,也可以通过这个拓展来修改对象
  9. 调用实现了 SmartInitializingSingleton 接口类的 afterSingletonsInstantiated() 方法;这个时候所有的Bean已经实例化完成,后续加入的Bean不会受Bean工厂的后置处理器影响
  10. 监听Spring容器启动事件 ContextRefreshedEvent

相关文章

网友评论

    本文标题:Spring源码启动过程以及拓展点

    本文链接:https://www.haomeiwen.com/subject/wqabsrtx.html