Spring-刷新应用上下文refreshContext

46次阅读

共计 26289 个字符,预计需要花费 66 分钟才能阅读完成。

1. 简介

本篇文章是针对上篇文章启动原理的补充,主要介绍 Spring IOC 容器初始化中刷新应用上下文操作。

2. 代码解析

查看源码发现 refreshContext(context) –> refresh(context) –> ApplicationContext.refresh()
所以我们这里详细说一下这个 refresh()方法。
代码如下:

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
            // 第一步:容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等
            prepareRefresh();
            
            // 第二步:获取新的 beanFactory,销毁原有 beanFactory、为每个 bean 生成 BeanDefinition 等, 注意此处是获取新的,销毁旧的,这就是刷新的意义(Spring 容器里通过 BeanDefinition 对象来表示 Bean,BeanDefinition 描述了 Bean 的配置信息。)
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        
            // 第三步:配置标准的 beanFactory,设置 ClassLoader,设置 SpEL 表达式解析器等
            prepareBeanFactory(beanFactory);
            try {
                // 第四步:在所有的 beanDenifition 加载完成之后,bean 实例化之前执行。比如在 beanfactory 加载完成所有的 bean 后,想修改其中某个 bean 的定义,或者对 beanFactory 做一些其他的配置,就可以在子类中对 beanFactory 进行后置处理。postProcessBeanFactory(beanFactory);

                // 第五步:实例化并调用所有注册的 beanFactory 后置处理器(实现接口 BeanFactoryPostProcessor 的 bean)invokeBeanFactoryPostProcessors(beanFactory);
         
               // 第六步:实例化和注册 beanFactory 中扩展了 BeanPostProcessor 的 bean。// 例如:AutowiredAnnotationBeanPostProcessor(处理被 @Autowired 注解修饰的 bean 并注入)
                //RequiredAnnotationBeanPostProcessor(处理被 @Required 注解修饰的方法)
                //CommonAnnotationBeanPostProcessor(处理 @PreDestroy、@PostConstruct、@Resource 等多个注解的作用)等。registerBeanPostProcessors(beanFactory);

                // 第七步:初始化国际化工具类 MessageSource
                initMessageSource();

                // 第八步:初始化应用事件广播器。这是观察者模式的典型应用。我们知道观察者模式由主题 Subject 和 Observer 组成。广播器相当于主题 Subject,其包含多个监听器。当主题发生变化时会通知所有的监听器。初始化应用消息广播器,并放入 "ApplicationEventMulticaster" Bean 中
                initApplicationEventMulticaster();

                // 第九步:这个方法在 AnnotationApplicationContex 上下文中没有实现,留给子类来初始化其他的 Bean,是个模板方法,在容器刷新的时候可以自定义逻辑(子类自己去实现逻辑),不同的 Spring 容器做不同的事情
                onRefresh();

                // 第十步:注册监听器,并且广播 early application events, 也就是早期的事件
                registerListeners();

                // 第十一步:初始化剩下的单例(非懒加载的单例类)(并 invoke BeanPostProcessors)// 实例化所有剩余的(非懒加载)单例 Bean。(也就是我们自己定义的那些 Bean)// 比如 invokeBeanFactoryPostProcessors 方法中根据各种注解解析出来的类,在这个时候都会被初始化,扫描的 @Bean 之类的,// 实例化的过程各种 BeanPostProcessor 开始起作用
                finishBeanFactoryInitialization(beanFactory);

                // 第十二步:完成刷新过程,通知生命周期处理器 lifecycleProcessor 完成刷新过程,同时发出 ContextRefreshEvent 通知别人
                //refresh 做完之后需要做的其他事情
                // 清除上下文资源缓存(如扫描中的 ASM 元数据)// 初始化上下文的生命周期处理器,并刷新(找出 Spring 容器中实现了 Lifecycle 接口的 bean 并执行 start()方法)。// 发布 ContextRefreshedEvent 事件告知对应的 ApplicationListener 进行响应的操作
                finishRefresh();}

            catch (BeansException ex) {if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization -" +
                            "cancelling refresh attempt:" + ex);
                }
               // 如果刷新失败那么就会将已经创建好的单例 Bean 销毁掉
                destroyBeans();

                // 重置 context 的活动状态 告知是失败的
                cancelRefresh(ex);

                // 抛出异常
                throw ex;
            }

            finally {
                // 失败与否,都会重置 Spring 内核的缓存。因为可能不再需要 metadata 给单例 Bean 了。resetCommonCaches();}
        }
    }

2.1 第一步:容器刷新前的准备

protected void prepareRefresh() {
        // 记录容器启动时间,然后设立对应的标志位
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);
        // 打印 info 日志:开始刷新当前容器了
        if (logger.isInfoEnabled()) {logger.info("Refreshing" + this);
        }

        // 这是扩展方法,由子类去实现,可以在验证之前为系统属性设置一些值可以在子类中实现此方法
        // 因为我们这边是 AnnotationConfigApplicationContext,可以看到不管父类还是自己,都什么都没做,所以此处先忽略
        initPropertySources();

        // 属性文件验证,确保需要的文件都已经放入环境中
        getEnvironment().validateRequiredProperties();

        // 初始化容器,用于装载早期的一些事件
        this.earlyApplicationEvents = new LinkedHashSet<>();}

2.2 第二步:获取新的 beanFactory

obtainFreshBeanFactory()方法会解析所有 Spring 配置文件(通常我们会放在 resources 目录下),将所有 Spring 配置文件中的 bean 定义封装成 BeanDefinition,加载到 BeanFactory 中。常见的,如果解析到 <context:component-scan base-package=”” /> 注解时,会扫描 base-package 指定的目录,将该目录下使用指定注解(@Controller、@Service、@Component、@Repository)的 bean 定义也同样封装成 BeanDefinition,加载到 BeanFactory 中。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        // 初始化 BeanFactory
        refreshBeanFactory();
        // 返回初始化之后的 BeanFactory
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {logger.debug("Bean factory for" + getDisplayName() + ":" + beanFactory);
        }
        return beanFactory;
    }
protected final void refreshBeanFactory() throws BeansException {
        // 判断是否已经存在 BeanFactory,存在则销毁所有 Beans,并且关闭 BeanFactory
        if (hasBeanFactory()) {
            // 销毁所有的 bean
            destroyBeans();
            // 关闭并销毁 BeanFactory
            closeBeanFactory();}
        try {
           // 创建具体的 beanFactory,这里创建的是 DefaultListableBeanFactory,最重要的 beanFactory spring 注册及加载 bean 就靠它
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            // 定制 BeanFactory,包括是否允许覆盖同名称的不同定义的对象以及循环依赖
            customizeBeanFactory(beanFactory);
            // 这个就是最重要的了,加载所有的 Bean 配置信息(属于模版方法,由子类去实现加载的方式)loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}
        }
        catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for" + getDisplayName(), ex);
        }
    }
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
        //allowBeanDefinitionOverriding 属性是指是否允对一个名字相同但 definition 不同进行重新注册,默认是 true。if (this.allowBeanDefinitionOverriding != null) {beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
        }
         //allowCircularReferences 属性是指是否允许 Bean 之间循环引用,默认是 true.
        if (this.allowCircularReferences != null) {beanFactory.setAllowCircularReferences(this.allowCircularReferences);
        }
    }

实现 loadBeanDefinitions()的子类有多种,如 AbstractXmlApplicationContext 类提供了基于 XML 的加载实现,AnnotationConfigWebApplicationContext 类提供了在 webapp 的场景下基于注解配置的加载实现,XmlWebApplicationContext 类提供了在 webapp 场景下基于 xml 配置的加载实现,XmlPortletApplicationContext 提供了在 portalet 下基于 xml 配置的加载实现,GroovyWebApplicationContext 类提供了基于 groovy 脚本配置的加载实现。

下面以 AnnotationConfigWebApplicationContext#loadBeanDefinitions()方法为例看下代码。

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
        // 初始化这个脚手架 其实就是直接 new 出实例
       AnnotatedBeanDefinitionReader reader = getAnnotatedBeanDefinitionReader(beanFactory);
        ClassPathBeanDefinitionScanner scanner = getClassPathBeanDefinitionScanner(beanFactory);
        // 生成 Bean 的名称的生成器,如果自己没有 setBeanNameGenerator(可以自定义), 这里目前为 null
        BeanNameGenerator beanNameGenerator = getBeanNameGenerator();
        if (beanNameGenerator != null) {reader.setBeanNameGenerator(beanNameGenerator);
            scanner.setBeanNameGenerator(beanNameGenerator);
            // 若我们注册了 beanName 生成器,那么就会注册进容器里面
            beanFactory.registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);
        }
        
        // 这是给 reader 和 scanner 注册 scope 的解析器  此处为 null
        ScopeMetadataResolver scopeMetadataResolver = getScopeMetadataResolver();
        if (scopeMetadataResolver != null) {reader.setScopeMetadataResolver(scopeMetadataResolver);
            scanner.setScopeMetadataResolver(scopeMetadataResolver);
        }

        // 我们可以自己指定 annotatedClasses 配置文件, 同时也可以交给下面扫描
        if (!this.annotatedClasses.isEmpty()) {
            // 这里会把所有的配置文件输出 =======info 日志  请注意观察控制台
            if (logger.isDebugEnabled()) {
                logger.debug("Registering annotated classes: [" +
                        StringUtils.collectionToCommaDelimitedString(this.annotatedClasses) + "]");
            }
            // 若是指明的 Bean,就交给 reader 去处理
            reader.register(ClassUtils.toClassArray(this.annotatedClasses));
        }

        // 也可以是包扫描的方式,扫描配置文件的 Bean
        if (!this.basePackages.isEmpty()) {if (logger.isDebugEnabled()) {
                logger.debug("Scanning base packages: [" +
                        StringUtils.collectionToCommaDelimitedString(this.basePackages) + "]");
            }
            scanner.scan(StringUtils.toStringArray(this.basePackages));
        }

        // 此处的意思是,也可以以全类名的形式注册。比如可以调用 setConfigLocations 设置(这在 xml 配置中使用较多)可以是全类名,也可以是包路径
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {for (String configLocation : configLocations) {
                try {Class<?> clazz = ClassUtils.forName(configLocation, getClassLoader());
                    if (logger.isTraceEnabled()) {logger.trace("Registering [" + configLocation + "]");
                    }
                    reader.register(clazz);
                }
                catch (ClassNotFoundException ex) {if (logger.isTraceEnabled()) {
                        logger.trace("Could not load class for config location [" + configLocation +
                                "] - trying package scan." + ex);
                    }
                    int count = scanner.scan(configLocation);
                   // 发现不是全类名,那就当作包扫描
                    if (count == 0 && logger.isDebugEnabled()) {logger.debug("No annotated classes found for specified class/package [" + configLocation + "]");
                    }
                }
            }
        }
    }

该方法主要是解析我们项目配置的 application.xml、xxx.xml 定义的 import、bean、resource、profile、、、、、。或扫描注解 将其属性封装到 BeanDefinition 对象中。

上面提到的“加载到 BeanFactory 中”的内容主要指的是添加到以下 3 个缓存:
beanDefinitionNames 缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 集合。
beanDefinitionMap 缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和 BeanDefinition 映射(Map<String, BeanDefinition>,beanName–key 和 beanDefinition–value)。
aliasMap 缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和别名映射。

现在 BeanFactory 已经创建完成了,并且 Config 配置文件的 Bean 定义已经注册完成了(备注:其它单例 Bean 是还没有解析的),下面的步骤大都把 BeanFactory 传进去了,都是基于此 Bean 工厂的操作。

2.3 第三步:配置标准的 beanFactory

至此,spring 已经完成了对配置的解析,开始 ApplicationContext 功能上的扩展。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 设置 beanFactory 的 classLoader 为当前 context 的 classLoader
        beanFactory.setBeanClassLoader(getClassLoader());
        // 设置 EL 表达式解析器(Bean 初始化完成后填充属性时会用到)beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        // 设置属性注册解析器 PropertyEditor 这个主要是对 bean 的属性等设置管理的一个工具
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        // 将当前的 ApplicationContext 对象交给 ApplicationContextAwareProcessor 类来处理,从而在 Aware 接口实现类中的注入 applicationContext 等等
        // 添加了一个处理 aware 相关接口的 beanPostProcessor 扩展,主要是使用 beanPostProcessor 的 postProcessBeforeInitialization()前置处理方法实现 aware 相关接口的功能
        // 类似的还有下面的 ResourceLoaderAware、ServletContextAware 等等等等
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        
        // 设置几个忽略自动装配的接口(默认只有 BeanFactoryAware 被忽略, 所以其它的需要自行设置)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 的类,就注册 beanFactory
        //  如果是 ResourceLoader、ApplicationEventPublisher、ApplicationContext 等等就注入当前对象 this(applicationContext 对象)
        
        // 此处 registerResolvableDependency()方法注意:它会把他们加入到 DefaultListableBeanFactory 的 resolvableDependencies 字段里面缓存这,供后面处理依赖注入的时候使用 DefaultListableBeanFactory#resolveDependency 处理依赖关系
        // 这也是为什么我们可以通过依赖注入的方式,直接注入这几个对象比如 ApplicationContext 可以直接依赖注入
        // 但是需要注意的是:这些 Bean,Spring 的 IOC 容器里其实是没有的。beanFactory.getBeanDefinitionNames()和 beanFactory.getSingletonNames()都是找不到他们的,所以特别需要理解这一点
        // 至于容器中没有,但是我们还是可以 @Autowired 直接注入的有哪些,请看下图
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        // 注册这个 Bean 的后置处理器:在 Bean 初始化后检查是否实现了 ApplicationListener 接口
        // 是则加入当前的 applicationContext 的 applicationListeners 列表 这样后面广播事件也就方便了
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

         // 检查容器中是否包含名称为 loadTimeWeaver 的 bean,实际上是增加 Aspectj 的支持
        // AspectJ 采用编译期织入、类加载期织入两种方式进行切面的织入
        // 类加载期织入简称为 LTW(Load Time Weaving), 通过特殊的类加载器来代理 JVM 默认的类加
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            // 添加 BEAN 后置处理器:LoadTimeWeaverAwareProcessor
            // 在 BEAN 初始化之前检查 BEAN 是否实现了 LoadTimeWeaverAware 接口,// 如果是,则进行加载时织入,即静态代理。beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));

            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        // 注入一些系统环境的 bean,比如 environment、systemProperties、SystemEnvironment 等
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
    }

附:IOC 容器中没有 Bean,但是我们还是可以依赖注入的 Bean 如下(resolvableDependencies):

主要扩展:1. 增加对 SPEL 语言的支持;
2. 增加对属性编辑器的支持,这些 PropertyEditors 在这里只是注册,使用的时候是将 bean 包装成 BeanWrapper,包装后的 BeanWrapper 的就包含了所有的这些 PropertyEditors,以便后期给 bean 设置属性的时候使用;
3. 增加对一些内置类(实际上就是前置处理器),比如 Aware 接口的信息注入;
4. 设置依赖功能可忽略的接口;
5. 注册一些固定的 bean,这些都是特殊的依赖解析,比如当注册了 BeanFactory.class 的依赖解析之后,当 bean 的属性注入的时候,一旦检测到属性为 BeanFactory 类型便会将 beanFactory 的实例注入进去;
6. 增加对 AspectJ 的支持;
7. 将相关环境变量及属性以单例模式注册。

2.4 第四步:postProcessBeanFactory 方法

到这里 beanFactory 都准备好了,子类可以自己去实现自己的逻辑。所以 postProcessBeanFactory 这个模版方法用于子类对 beanFactory 进行后置处理。比如一些 web 的 ApplicationContext,就实现了自己的逻辑,做一些自己的 web 相关的事情。此处我们看下 AbstractRefreshableWebApplicationContext#postProcessBeanFactory 方法:

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 注册 ServletContextAwareProcessor 这样任意 Bean 都可以很方便的获取到 ServletContext 了  同时忽略另外两个,因为 ServletContextAwareProcessor 都把事情都做了
        beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
        beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
        // 注册 web 环境,包括 request、session、golableSession、application
        WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
        // 注册 servletContext、contextParamters、contextAttributes、servletConfig 单例 bean
       WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
    }

2.5 第五步:激活各种 BeanFactory 处理器

invokeBeanFactoryPostProcessors 执行 BeanFactory 后置处理器,前提是你已经在容器中注册过此处理器了。这个接口跟 BeanPostProcessor 类似,可以对 bean 的定义(配置元数据)进行处理,作用范围是容器级的,只对自己的容器的 bean 进行处理。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 1.getBeanFactoryPostProcessors(): 拿到当前应用上下文 beanFactoryPostProcessors 变量中的值
    // 2.invokeBeanFactoryPostProcessors: 实例化并调用所有已注册的 BeanFactoryPostProcessor    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

        // 这里就是定制:如果 loadTimeWeaver 这个 Bean 存在,那么就会配置上运行时织入的处理器 LoadTimeWeaverAwareProcessor
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }

拿到当前应用上下文 beanFactoryPostProcessors 变量中的值.

public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {return this.beanFactoryPostProcessors;}

它不是返回 Spring 容器里面的 Processors,而是你自己的注册的(你自己手动 set 的),也就是说我们自己手动调用 set 方法添加进去,就能够执行。并不需要自己配置 @Bean 或者在 xml 里配置,那么重点就在于 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors:

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        // 这个 doc 说明很清楚:不管怎么样,先执行 BeanDefinitionRegistryPostProcessors 
        // 需要注意的是 BeanDefinitionRegistryPostProcessors 为 BeanFactoryPostProcessor 的子接口 它新增了方法:void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
        // BeanFactoryPostProcessor 的方法为;void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
        // 所以 BeanDefinitionRegistryPostProcessors,我们介入并改变 Bean 的一些定义信息
        Set<String> processedBeans = new HashSet<>();
        // 1. 判断 beanFactory 是否为 BeanDefinitionRegistry,beanFactory 为 DefaultListableBeanFactory,
    // 而 DefaultListableBeanFactory 实现了 BeanDefinitionRegistry 接口,因此这边为 true
    
        //1. 只有此 beanFactory 是 BeanDefinitionRegistry 才能执行 BeanDefinitionRegistryPostProcessor,才能修改 Bean 的定义(beanFactory 为 DefaultListableBeanFactory, 而 DefaultListableBeanFactory 实现了 BeanDefinitionRegistry 接口,因此这边为 true)if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 用于存放普通的 BeanFactoryPostProcessor
            List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
            // 用于存放 BeanDefinitionRegistryPostProcessor
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();
            都是 LinkedList,所以执行顺序和 set 进去的顺序是保持一样的
        // 2. 首先处理入参中的 beanFactoryPostProcessors
        // 遍历所有的 beanFactoryPostProcessors, 将 BeanDefinitionRegistryPostProcessor 和普通 BeanFactoryPostProcessor 区分开
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                // 2.1 如果是 BeanDefinitionRegistryPostProcessor
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                
                // 2.1.1 直接执行 BeanDefinitionRegistryPostProcessor 接口的 postProcessBeanDefinitionRegistry 方法    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                // 2.1.2 添加到 registryProcessors(用于最后执行 postProcessBeanFactory 方法)    registryProcessors.add(registryProcessor);
                }
                else {
                    // 2.2 否则,只是普通的 BeanFactoryPostProcessor
                // 2.2.1 添加到 regularPostProcessors(用于最后执行 postProcessBeanFactory 方法)regularPostProcessors.add(postProcessor);
                }
            }

             // 用于保存本次要执行的 BeanDefinitionRegistryPostProcessor
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // 3. 调用所有实现 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor 实现类
        // 3.1 找出所有实现 BeanDefinitionRegistryPostProcessor 接口的 Bean 的 beanName
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                    // 3.2 遍历 postProcessorNames
            for (String ppName : postProcessorNames) {
                // 3.3 校验是否实现了 PriorityOrdered 接口
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 3.4 获取 ppName 对应的 bean 实例, 添加到 currentRegistryProcessors 中,
                // beanFactory.getBean: 这边 getBean 方法会触发创建 ppName 对应的 bean 对象, 目前暂不深入解析 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                // 3.5 将要被执行的加入 processedBeans,避免后续重复执行
                    processedBeans.add(ppName);
                }
            }
            // 3.6 进行排序(根据是否实现 PriorityOrdered、Ordered 接口和 order 值来排序)
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 3.7 添加到 registryProcessors(用于最后执行 postProcessBeanFactory 方法)
            registryProcessors.addAll(currentRegistryProcessors);
            // 3.8 遍历 currentRegistryProcessors, 执行 postProcessBeanDefinitionRegistry 方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 3.9 执行完毕后, 清空 currentRegistryProcessors
            currentRegistryProcessors.clear();

            // 4. 调用所有实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessor 实现类(过程跟上面的步骤 3 基本一样)// 4.1 找出所有实现 BeanDefinitionRegistryPostProcessor 接口的类, 这边重复查找是因为执行完上面的 BeanDefinitionRegistryPostProcessor,
        // 可能会新增了其他的 BeanDefinitionRegistryPostProcessor, 因此需要重新查找

            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 校验是否实现了 Ordered 接口,并且还未执行过
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            // 4.2 遍历 currentRegistryProcessors, 执行 postProcessBeanDefinitionRegistry 方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // 5. 最后, 调用所有剩下的 BeanDefinitionRegistryPostProcessors
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                // 5.1 找出所有实现 BeanDefinitionRegistryPostProcessor 接口的类
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {                  // 5.2 跳过已经执行过的
                    if (!processedBeans.contains(ppName)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        // 5.3 如果有 BeanDefinitionRegistryPostProcessor 被执行, 则有可能会产生新的 BeanDefinitionRegistryPostProcessor,
                    // 因此这边将 reiterate 赋值为 true, 代表需要再循环查找一次
                        reiterate = true;
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                // 5.4 遍历 currentRegistryProcessors, 执行 postProcessBeanDefinitionRegistry 方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();}

            
        // 6. 调用所有 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory 方法(BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor)
        
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            // 7. 最后, 调用入参 beanFactoryPostProcessors 中的普通 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            // Invoke factory processors registered with the context instance.
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

// 到这里 , 入参 beanFactoryPostProcessors 和容器中的所有 BeanDefinitionRegistryPostProcessor 已经全部处理完毕,
    // 下面开始处理容器中的所有 BeanFactoryPostProcessor
        
        
    // 8. 找出所有实现 BeanFactoryPostProcessor 接口的类
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // 用于存放实现了 PriorityOrdered 接口的 BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        // 用于存放实现了 Ordered 接口的 BeanFactoryPostProcessor 的 beanName
        List<String> orderedPostProcessorNames = new ArrayList<>();
        // 用于存放普通 BeanFactoryPostProcessor 的 beanName
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        // 8.1 遍历 postProcessorNames, 将 BeanFactoryPostProcessor 按实现 PriorityOrdered、实现 Ordered 接口、普通三种区分开
        for (String ppName : postProcessorNames) {
        // 8.2 跳过已经执行过的
            if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {// 8.3 添加实现了 PriorityOrdered 接口的 BeanFactoryPostProcessor               priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            // 8.4 添加实现了 Ordered 接口的 BeanFactoryPostProcessor 的 beanName

                orderedPostProcessorNames.add(ppName);
            }
            else {
            // 8.5 添加剩下的普通 BeanFactoryPostProcessor 的 beanName
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // 9. 调用所有实现 PriorityOrdered 接口的 BeanFactoryPostProcessor
    // 9.1 对 priorityOrderedPostProcessors 排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        // 9.2 遍历 priorityOrderedPostProcessors, 执行 postProcessBeanFactory 方法
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // 10. 调用所有实现 Ordered 接口的 BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : orderedPostProcessorNames) {
            // 10.1 获取 postProcessorName 对应的 bean 实例, 添加到 orderedPostProcessors, 准备执行
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        // 10.2 对 orderedPostProcessors 排序
        sortPostProcessors(orderedPostProcessors, beanFactory);
        // 10.3 遍历 orderedPostProcessors, 执行 postProcessBeanFactory 方法
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // 11. 调用所有剩下的 BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            // 11.1 获取 postProcessorName 对应的 bean 实例, 添加到 nonOrderedPostProcessors, 准备执行
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        // 11.2 遍历 nonOrderedPostProcessors, 执行 postProcessBeanFactory 方法
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        / 12. 清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),// 因为后处理器可能已经修改了原始元数据,例如,替换值中的占位符...
        beanFactory.clearMetadataCache();}

invokeBeanFactoryPostProcessors(beanFactory)这一步主要做了:

  • 执行了 BeanDefinitionRegistryPostProcessor(此处只有 ConfigurationClassPostProcessor)
  • 执行了 BeanFactoryPostProcessor
  • 完成了 @Configuration 配置文件的解析,并且把扫描到的、配置的 Bean 定义信息都加载进容器里
  • Full 模式下,完成了对 @Configuration 配置文件的加强,使得管理 Bean 依赖关系更加的方便了

到这里 Bean 工厂完全准备好了,并且也注册好了所有的 Bean 的定义信息(此时 Bean 还并没有创建)。也完成了对配置文件的解析,可以说 Spring IOC 容器的大部分准备工作已经完成了,接下来就是对 Bean 的一些初始化、操作

2.6 第六步:注册 BeanPostProcessors

略。。。

2.7 第七步:为上下文初始化 Message 源,即不同语言的消息体,国际化处理

略。。。

2.8 第八步:initApplicationEventMulticaster

略。。。

2.9 第九步:

略。。。

2.10 第十步:registerListeners

在所有注册的 Bean 中查找 Listenter bean,注册到消息广播器中。

protected void registerListeners() {
        // 首先注册静态注册的监听器(代码注册的)for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);
        }

        // 获取容器中所有配置的 listener 并注册
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // 对 earlyApplicationEvents 这些事件进行广播,实际上就是遍历所有的 listener,找到可以处理 event 的 listener 处理
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

2.11 第十一步:finishBeanFactoryInitialization

初始化剩下的非惰性单例,如果某个单例依赖了惰性的单例,那么这个惰性的单例也会被初始化,这个很好理解吧。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 初始化 ConversionService,跟 PropertyEditor 类似
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
            beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        }

        // 则注册默认的嵌入值解析器
    // 例如 PropertyPlaceholderConfigurer bean)之前注册过:// 主要用于注解属性值的解析。if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }

        // 单例 bean 初始化之前首先初始化 LoadTimeWeaverAware,以支持 aop,AspectJ
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);
        }

        // Stop using the temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(null);

        // 冻结 bean 定义(BeanDefinition),表示所有的 bean 定义进不被修改或进行进一步处理
        beanFactory.freezeConfiguration();

        // 初始化非惰性单例,实际上就是遍历所有的 beanName,然后一一调用 getBean()
        beanFactory.preInstantiateSingletons();}

2.12 第十二步:finishRefresh

protected void finishRefresh() {// 清除上下文级别 (context-level) 的资源缓存,比如由 scanning 产生的 ASM 元数据
        clearResourceCaches();

        // 初始化 LifecycleProcessor
        initLifecycleProcessor();

         // 使用 LifecycleProcessor 来启动 Lifecycle 子类
        getLifecycleProcessor().onRefresh();

        // 上下文刷新完成,发布事件
        publishEvent(new ContextRefreshedEvent(this));

        // Participate in LiveBeansView MBean, if active.
        LiveBeansView.registerApplicationContext(this);
    }

初始化 LifecycleProcessor 的时候,跟初始化 MessageResource 一样,没有自定义的就是用默认的 DefaultLifecycleProcessor。

getLifecycleProcessor().onRefresh()会使用我们注册的 LyfecycleProcessor 来启动我们注册的 SmartLifeCycle 的子类。看一下代码吧。

// 默认的 DefaultLifecycleProcessor.java
public void onRefresh() {startBeans(true);
        this.running = true;
    }
private void startBeans(boolean autoStartupOnly) {
        // 获取所有的 LifeCycle 类型的 bean
        Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
        Map<Integer, LifecycleGroup> phases = new HashMap<>();
        lifecycleBeans.forEach((beanName, bean) -> {
            // 默认的 DefaultLifecycleProcessor 只会启动 SmartLifecycle 的,或者非自动启动的类型
        //SmartLifecycle 继承了 Phases 接口
            if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {int phase = getPhase(bean);
                LifecycleGroup group = phases.get(phase);
                if (group == null) {group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                     // 添加到需要启动的集合中
                    phases.put(phase, group);
                }
                group.add(beanName, bean);
            }
        });
        // 启动需要启动的这些 LifeCycle
        if (!phases.isEmpty()) {List<Integer> keys = new ArrayList<>(phases.keySet());
            Collections.sort(keys);
            for (Integer key : keys) {phases.get(key).start();}
        }
    }

这一步主要完成以下操作:

  • 完成容器的初始化过程, 发布相应事件。
  • 启动容器的声明周期处理器。管理容器声明周期。
  • 发布 ContextRefreshedEvent 事件。
  • 启动内嵌的 Servlet 容器。
  • 发布容器启动事件。

3 总结

Spring 刷新应用上下文操作简要划分为 12 步操作流程:
1. 准备刷新 —>2. 获取刷新 bean 工厂 —>3. 准备 bean 工厂 —>4. 前处理 bean 工厂 —>

5. 调用 bean 工厂前处理器 —>6. 注册 bean 前处理器 —>7. 初始化消息源 —>8. 初始化应用事件发布器 —>

9. 刷新 —>10. 注册监听器 —>11. 完成 bean 工厂初始化 —>12. 完成刷新.

正文完
 0