Spring容器的refresh方法

Spring容器的refresh方法

BeanFactory的创建以及准备

  1. prepareRefresh 刷新前的预处理
    1. initPropertySources() 初始化一些设置; 子类自定义个性化的属性设置方法;
    2. getEnvironment().validateRequiredProperties(); 校验属性的合法等
    3. this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);保存容器中一些早期的事件;
  2. obtainFreshBeanFactory(); 获取BeanFactory
    1. refreshBeanFactory();
      1. 创建了一个 this.beanFactory = new DefaultListableBeanFactory();
      2. 设置id
    2. getBeanFactory() 返回上一步的beanFactory
    3. 将创建的BeanFactory返回
  3. prepareBeanFactory(beanFactory); BeanFactory的准备工作(BeanFactory进行一些设置)
    1. 设置BeanFactory的类加载器, 支持表达式解析器
    2. 添加部分BeanPostProcessor [ApplicationContextAwareProcessor]
    3. 设置忽略的自动装配的接口 [EnvironmentAware,EmbeddedValueResolverAware…]
    4. 注册可以解析的自动装配 ,我们可以在任何组件中自动注入[BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext]
    5. 添加BeanPostProcessor
    6. 添加编译时的AspectJ支持
    7. 给BeanFactory中注册一些能用的组件:
      1. environment
      2. systemProperties
      3. systemEnvironment
  4. postProcessBeanFactory(beanFactory); BeanFactory准备工作完成后进行的后置处理工作
    1. 子类通过重写这个方法在BeanFactory创建并准备完成后进一步的设置

BeanFactoryPostProcessor

接着往下说

  1. invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessors;

    1. BeanFactoryPostProcessors: BeanFactory的后置处理器, 在BeanFactory标准初始化之后进行的
      1. 两个相关接口: BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor
      2. 执行BeanFactoryPostProcessor的方法
        1. 先执行BeanDefinitionRegistryPostProcessor
          1. 获取所有的BeanDefinitionRegistryPostProcessor
          2. 按照优先级排序: PriorityOrdered -> Ordered指定顺序的 -> 没有实行任何优先级或者顺序接口的
        2. 再执行BeanFactoryPostProcessor
  2. registerBeanPostProcessors(beanFactory);` 注册bean的后置处理器

    不同接口类型的BeanPostProcessor, 在Bean创建前后执行时机是不一样的

    DestructionAwareBeanPostProcessor

    InstantiationAwareBeanPostProcessor

    SmartInstantiationAwareBeanPostProcessor

    MergedBeanDefinitionPostProcessor

    1. 获取所有的BeanPostProcessor beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

      后置处理器都默认可以通过PriorityOrdered,Ordered接口来指定优先级

    2. 先注册PritorityOrdered优先级接口的BeanPostProcessor

      beanFactory.addBeanPostProcessor(postProcessor)

    3. 再注册Ordered接口的

    4. 最后注册没有实现优先级接口的

    5. 最终注册MergedBeanDefinitionPostProcessor

    6. 这测一个ApplicationListenerDetector: 在Bean创建完成后检查是否是ApplicationListener, 如果是,this.applicationContext.addApplicationListener

国际化

  1. initMessageSource() 初始化MessageSource组件(做国际化,消息绑定,消息解析)
    1. 获取BeanFactory
    2. 看容器中是否有id为messageSource的, 类型是MessageSource的组件
      1. 如果有赋值给MessageSource, 如果没有, 自己创建一个DelegatingMessageSource
    3. 把创建好的MessageSource注册在容器中; 以后获取国际化配置文件值的时候,可以自动注入MessageSource

时间派发器

  1. initApplicationEventMulticaster 初始化事件派发器
    1. 获取BeanFactory
    2. 从BeanFactory中获取 applicationEventMulticaster (可以自行配置)
    3. 如果没有配置, 创建一个SimpleApplicationEventMulticaster
    4. 将创建的 applicationEventMulticaster 注入到容器 registerSingleton
  1. onRefresh 留给子类
    1. 子类可以重写这个方法, 在容器刷新时自定义逻辑
  1. registerListeners 给容器中将所有项目里面的ApplicationListener注册进来
    1. 从容器中拿到所有的ApplicationListener
    2. 将每个监听器添加到事件派发器中
    3. 派发之前步骤产生的事件

初始化Bean

  1. finishBeanFactoryInitialization(beanFactory); 初始化所有剩下的单实例bean

    1. beanFactory.preInstantiateSingletons(); 初始化

      1. 获取容器中的所有Bean, 依次创建和初始化对象

      2. 获取Bean的定义信息 RootBeanDefinition

      3. Bean不是抽象的, 是单实例的, 不是LazyInit的. 进行创建

        1. 判断是否是FactoryBean, 也就是是否实现了此接口->使用工厂方法创建

        2. 不是工厂Bean, 使用getBean(beanName)创建 (这里的方法跟直接调用ioc.getBean一样)

          1. getBean(beanName)

          2. doGetBean(name, null, null, false);

          3. 先获取缓存中保存的单实例Bean, 如果能获取到, 说明这个Bean之前被创建过(所有创建过的Bean都会被缓存起来)

            private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); 是从这里获取

          4. 缓存中获取不到, 开始Bean的创建流程

          5. 标记当前bean被创建markBeanAsCreated

          6. 获取Bean的定义信息 getMergedLocalBeanDefinition

          7. 获取当前Bean依赖的其他Bean getDependsOn;(这个也是配置在Beandepends-on属性上的) 如果有, 按照getBean()把依赖的Bean先创建出来

          8. 启动单实例Bean的创建流程

            1. createBean(beanName, mbd, args)

            2. Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 让BeanPostProcessor先拦截返回代理对象

              1. 先触发applyBeanPostProcessorsBeforeInstantiation
              2. 如果有返回值applyBeanPostProcessorsAfterInitialization
            3. 如果前面的resolveBeforeInstantiation没有返回代理对象, 向下执行, 如果返回了代理对象, 结束创建.

            4. 调用 Object beanInstance = doCreateBean(beanName, mbdToUse, args);

              1. 创建Bean实例

                1. obtainFromSupplier 利用Supplier
                2. instantiateUsingFactoryMethod 利用工厂方法或构造器
              2. applyMergedBeanDefinitionPostProcessors 调用MergedBeanDefinitionPostProcessor

              3. 为属性赋值populateBean

                1. 拿到InstantiationAwareBeanPostProcessor后置处理器; 执行postProcessAfterInstantiation方法

                2. 拿到InstantiationAwareBeanPostProcessor; 执行postProcessProperties

                3. 赋值 应用Bean属性的值; 为属性利用setter方法进行赋值:

                  applyPropertyValues(beanName, mbd, bw, pvs);

              4. 初始化 initializeBean

                1. 执行Aware接口的方法invokeAwareMethods[如BeanNameAware\BeanClassLoaderAware\BeanFactoryAware]
                2. 执行后置处理器初始化之前的方法 applyBeanPostProcessorsBeforeInitialization
                3. 执行初始化方法 invokeInitMethods(beanName, wrappedBean, mbd);
                  1. 是否是InitializingBean接口实现, 执行接口规定的初始化
                  2. 是否是自定义初始化方法, 有则执行invokeCustomInitMethod
                4. 执行后置处理器初始化之后的方法applyBeanPostProcessorsAfterInitialization
              5. 注册销毁方法

            5. 将创建的Bean添加到缓存中singletonObjects

              说白了IOC容器就是这种各样的Map; 很多的Map保存了单实例Bean, 各种环境信息;

              所有的Bean都利用getBean创建完成后, 检查所有的Bean是否是SmartInitializingSingleton接口的; 如果是, 就执行afterSingletonsInstantiated

  2. finishRefresh() 完成BeanFactory的初始化创建工作 -> IOC容器创建完成

    1. initLifycycleProcessor() 获取生命周期有关的后置处理器 LifecycleProcessor

      加入到容器中

      默认从容器中找, 如果没有 new 一个DefaultLifecycleProcessor

      可以写一个

    2. 拿到处理器, 调用onRefresh方法

    3. 发布容器刷新完成时间publishEvent

至此, 粗略的刷新过程就是这样

总结

  1. Spring容器启动时会保存所有注册进来的Bean的定义信息
    1. xml
    2. annotation: @Service @Component @Bean
  2. Spring容器会在合适的实际创建Bean
    1. 用到这个bean的时候使用getBean方法创建, 创建好后保存在容器中
    2. 统一创建所有bean的时候``finishBeanFactoryInitialization`
  3. 后置处理器
    1. 每一个bean创建, 都会使用各种后置处理器进行处理, 来增强bean的功能
      • AnnotationAwareAspectJAutoProxyCreator AOP
      • AutowiredAnnotationBeanPostProcessor 处理自动注入
  4. 事件驱动器
    1. ApplicationListener 监听
    2. ApplicationEventMulticaster 事件派发器