zoukankan      html  css  js  c++  java
  • Spring源码解析(一)--Spring容器刷新

    Spring容器刷新的核心方法是AbstractApplicationContext.refresh();刷新容器,加上锁
    1 prepareRefresh();准备刷新容器
      1.1 修改状态(容器刷新时间、容器关闭状态、容器活跃状态)
      1.2 初始化属性资源(空实现,供子类实现)
      1.3 初始化环境资源(Environment),并校验必要的参数
      1.4 定义早期应用事件集合(earlyApplicationEvents),用于记录应用事件广播器(ApplicationEventMulticaster)初始化前推送的事件,在广播器初始化后调用
    2 obtainFreshBeanFactory();获取BeanFactory
      2.1 refreshBeanFactory()
        2.1.1 创建BeanFactory
        2.1.2 修改刷新状态refreshed
        2.1.3 设置序列号
      2.2 返回BeanFactory
    3 prepareBeanFactory(beanFactory); 初始化BeanFactory
      3.1 设置类加载器
      3.2 设置SPEL表达式解析器(SpelExpressionParser)
      3.3 设置资源编辑器(ResourceEditorRegistrar)
      3.4 增加Bean的后置处理器ApplicationContextAwareProcessor,用来处理Bean的Aware接口
        包括EnvironmentAware 环境数据,用于获取环境相关的信息
          EmbeddedValueResolverAware 表达式解析器,用于处理字符串表达式。比如"${spring.redis.port:6379}"
          ResourceLoaderAware 资源加载器,用于读取资源数据
          ApplicationEventPublisherAware 应用事件推送器,用于推送事件(ApplicationEvent)
          MessageSourceAware 用于国际化模块进行资源获取
          ApplicationContextAware 容器,用于获取容器
      3.5 设置Bean自动装配时忽略的接口,这些接口已由ApplicationContextAwareProcessor这个后置处理器处理
      3.6 设置Bean自动装配规则(对应关系),用于在Bean装配时设置所需要的类
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
        比如:@Autowired                  容器会注入this即当前容器
           private ApplicationContext applicationContext;
      3.7 注册Bean的后置处理器ApplicationListenerDetector,用于处理实现ApplicationEvent接口的类,将这些类注册到容器和事件广播器中
      3.8 注册Bean的后置处理器LoadTimeWeaverAwareProcessor,如果包含名为loadTimeWeaver的类的话,用于处理Bean的LoadTimeWeaverAware接口,并设置临时类加载器ContextTypeMatchClassLoader
      3.9 容器中注册Bean(environment、systemProperties、systemEnvironment)
    4 postProcessBeanFactory(beanFactory); 初始化BeanFactory后置事件(空实现,供子类实现)
    5 invokeBeanFactoryPostProcessors(beanFactory); 执行BeanFactory后置处理器
      注:BeanFactory的后置处理器有两类:BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor
      5.1 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
        getBeanFactoryPostProcessors() 为手动注入的BeanFactory后置处理器,默认情况下为空
        5.1.1 获取手动注入的BeanFactory后置处理器,若处理器类型为BeanDefinitionRegistryPostProcessor则执行postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法
        5.1.2 从容器中获取所有BeanDefinitionRegistryPostProcessor类型的后置处理器,并按照PriorityOrdered->Ordered->NonOrdered 的顺序进行执行
        5.1.3 执行手动注入中BeanFactoryPostProcessor类型的后置处理器,调用postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法
        5.1.4 从容器中获取所有BeanFactoryPostProcessor类型的后置处理器,并按照PriorityOrdered->Ordered->NonOrdered 的顺序进行执行
      5.2 因为在BeanFactory的后置处理器中可以手动注册类,所以重复3.8步操作,重新判断是否有名为loadTimeWeaver的类,有的话注册后置处理器LoadTimeWeaverAwareProcessor,并设置临时类加载器ContextTypeMatchClassLoader
    6 registerBeanPostProcessors(beanFactory);注册Bean的后置处理器
      6.1 从容器中获取所有BeanPostProcessor类型的后置处理器,将处理器分类PriorityOrdered、Ordered、Internal、NonOrdered
        按照PriorityOrdered->Ordered->NonOrdered->Internal的顺序依次注册Bean后置处理器
      6.2 重新注册Bean的后置处理器ApplicationListenerDetector,将该处理器移到最后,第一次注册见3.7
    7 initMessageSource();初始化国际化资源类
      7.1 判读容器中是否有名为messageSource的Bean
      7.2 如果有的话将其初始化,如果实现接口HierarchicalMessageSource,并且不存在父级MessageSource,则获取内部MessageSource注入为父级
      7.3 如果没有的话,初始化DelegatingMessageSource,设置父级为内部的MessageSource,并将其注入到Spring容器
    8 initApplicationEventMulticaster();初始化应用事件广播器,用于派发事件
      8.1 判断容器中是否有名为applicationEventMulticaster的Bean
      8.2 如果有的话将其初始化
      8.3 如果没有的话,初始化SimpleApplicationEventMulticaster,并将其注入到Spring容器
    9 onRefresh();刷新事件(空实现,供子类实现)
    10 registerListeners();注册ApplicationListener
      10.1 获取应用事件广播器(ApplicationEventMulticaster),在第8步已创建
      10.2 获取手动注册的ApplicationListener,将其依次注入到ApplicationEventMulticaster
      10.3 获取容器中所有的ApplicationListener,将其依次注入到ApplicationEventMulticaster
      10.4 获取早期应用事件,第1.4步定义的集合(若在之前通过容器推送事件,则会保存在该集合中),先把数据缓存到本地变量,并把集合赋值为NULL,赋值为NULL是为了防止推送事件仍然存入该集合(判断依据是该集合是否为NULL)。
      10.5 ApplicationEventMulticaster依次调用ApplicationListener的onApplicationEvent(E event)接口
    11 finishBeanFactoryInitialization(beanFactory);初始化所有单例的非延迟加载的Bean
      11.1 若容器中包含ConversionService,则设置BeanFacotry的ConversionService值
      11.2 若容器未设置表达式解析器EmbeddedValueResolverAware,则初始化容器的表达式解析器,默认StringValueResolver
      11.3 初始化LoadTimeWeaverAware接口的Bean
      11.4 清空临时类加载器,第3.8和5.2会设置该值
      11.5 冻结配置configurationFrozen = true;在调用getBeanNamesForType()时,会判断该值,若已冻结只会获取缓存中的信息。
      11.6 初始化单例的非延迟加载的Bean
        11.6.1 循环查看所有Bean描述,若Bean是非抽象的、单例的、非延迟加载的,则进行创建
        11.6.2 若Bean实现接口FactoryBean
          11.6.2.1 调用getBean("$" + beanName)方法
          11.6.2.2 判断Bean是否实现SmartFactoryBean接口并且isEagerInit()返回值为true,则调用getBean(beanName)
          11.6.3 若Bean未实现接口FactoryBean
            调用getBean(beanName),getBean方法实现查看文后链接
      11.7 所有单例非延迟加载的Bean初始化完成后,依次查看是否实现SmartInitializingSingleton接口若实现则调用afterSingletonsInstantiated()方法
    12 finishRefresh();完成刷新
      12.1 初始化生命周期处理器LifecycleProcessor,若容器中存在初始化,否则设置默认的DefaultLifecycleProcessor
      12.2 调用LifecycleProcessor的onRefresh()方法
      12.3 推动容器刷新完成事件
    13 resetCommonCaches();清除各种缓存


    《Spring源码解析(一)--Spring容器刷新》

    《Spring源码解析(二)--Spring Bean创建》

    《Spring源码解析(三)--AOP实现原理》

  • 相关阅读:
    使用AOP 实现Redis缓存注解,支持SPEL
    springmvc 双亲上下文导致的 No mapping found for HTTP request
    调用iframe 中的js[兼容各种浏览器]
    NIO学习:异步IO实例
    byte数组与对象之间的相互转换
    NIO学习:buffer读入与写出(文件复制示例)
    NIO学习:使用Channel、Buffer写入文件
    使用摘要流获取文件的MD5
    ActiveMQ入门实例
    获取java项目 classpath目录
  • 原文地址:https://www.cnblogs.com/zhuqianchang/p/11413594.html
Copyright © 2011-2022 走看看