• 欢迎访问 winrains 的个人网站!
  • 本网站主要从互联网整理和收集了与Java、网络安全、Linux等技术相关的文章,供学习和研究使用。如有侵权,请留言告知,谢谢!

Spring 刷新应用上下文refreshContext

Spring winrains 来源:模范青蛙 11个月前 (11-05) 46次浏览

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 第九步:onRefresh()

在接触SpringBoot之前我们的web项目都是需要部署到web服务容器上,如tomcat、weblogic、JBoss等,然后启动web容器真正运行我们的系统。
SpringBoot给我们带来了一个全新的开发体验,我们可以把web程序打成jar包,直接启动,这得益于SpringBoot内置了容器,可以直接启动,本文将以Tomcat为例,来看看SpringBoot是如何启动Tomcat的,同时也将展开学习下Tomcat的源码,了解Tomcat的设计。
启动Tomcat是在“刷新上下文”操作中;Tomcat的启动主要是初始化2个核心组件,连接器(Connector)和容器(Container),一个Tomcat实例就是一个Server,一个Server包含多个Service,也就是多个应用程序,每个Service包含多个连接器(Connetor)和一个容器(Container),而容器下又有多个子容器,按照父子关系分别为:Engine,Host,Context,Wrapper,其中除了Engine外,其余的容器都是可以有多个。
在onReFresh创建内置tomcat,在finishRefresh启动tomcat

tomcat的编码有点意思 我们获取任何一个容器的时候,在他内部都会包含获取其父容器的方法

onRefresh()方法是调用其子类的实现,根据我们上文的分析,我们这里的子类是ServletWebServerApplicationContext。
http://image.winrains.cn/2019/11/20191105180857-564a6.png

// 类:ServletWebServerApplicationContext
protected void onRefresh() {
    super.onRefresh();
    try {
        createWebServer();
    } catch (Throwable ex) {
        throw new ApplicationContextException("Unable to start web server", ex);
    }
}
private void createWebServer() {
    WebServer webServer = this.webServer;
    ServletContext servletContext = getServletContext();
    // 如果webServer 和servletContext 都为空
    if (webServer == null && servletContext == null) {
        // 通过spring去加载ServletWebServerFactory
        ServletWebServerFactory factory = getWebServerFactory();
        // 创建webServer,这边getSelfInitializer里面就是我们spring容器
        this.webServer = factory.getWebServer(getSelfInitializer());
    } else if (servletContext != null) {
        try {
            // 如果servletContext 不为空,调用ServletContextInitializer数组去启动该容器,
            // 即给改servletContext配置servlet,filters,listeners context-params
            // 和attribute
            getSelfInitializer().onStartup(servletContext);
        } catch (ServletException ex) {
            throw new ApplicationContextException("Cannot initialize servlet context", ex);
        }
    }
    // 把我们创建好的额webServer好servletcontext,
    // 更新到ConfigurableWebEnvironment中
    // 前提是本身ConfigurableWebEnvironment就有这两个属性
    initPropertySources();
}

到这里,createWebServer()就是启动web服务,但是还没有真正启动Tomcat,既然webServer是通过ServletWebServerFactory来获取的,我们就来看看这个工厂的真面目。
http://image.winrains.cn/2019/11/20191105180857-e7979.png
根据上图我们发现,工厂类是一个接口,各个具体服务的实现是由各个子类来实现的,所以我们就去看看TomcatServletWebServerFactory.getWebServer()的实现。
创建webServer的过程,initializers就是spring的容器

@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
    // 创建tomcat
    Tomcat tomcat = new Tomcat();
    // 创建一个临时目录个给当前webServer,并注册了一个钩子在程序退出的时候删除文件夹
    File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
    // 设置tomcat的baseDir,baseDir是给临时文件使用的,
    // 应该是第一个被调用的方法,如果该方法没被调用,
    // 我们默认调用系统属性system properties - catalina.base, catalina.home
    // 或者[user.dir]/tomcat.$PORT
    tomcat.setBaseDir(baseDir.getAbsolutePath());
    // 根据protocol(默认是Http11NioProtocol)创建connector,
    // 这边的逻辑是先看下是否是http协议,然后再看看是否是AJP协议,
    // 如果都不是直接塞入协议的名字,然后下一步根据协议的名字调用class.forName得到协议类,
    // 然后通过org.apache.catalina.STRICT_SERVLET_COMPLIANCE属性设置整个tomcat的编码是ISO_8859_1还是UTF-8
    Connector connector = new Connector(this.protocol);
    // 给第一个service添加connector,这其中会初始化server(StandardServer)(server会初始化baseDir,设置初始化监听关闭端口为-1,这样就不会被从端口关闭,创建标准的service(StandardServer))然后绑定两者
    // addConnector:寻找现有的connector数组,将connector添加进去并把connector和service互相绑定,然后启动该connector
    tomcat.getService().addConnector(connector);
    // 设置我们自定义的端口号,添加server,bindOnInit属性,添加我们的协议,添加urlEncoding,设置ssl,compression
    customizeConnector(connector);
    // tomcat本身设置connector
    tomcat.setConnector(connector);
    // 关闭自动部署
    tomcat.getHost().setAutoDeploy(false);
    // 设置backgroundProcessorDelay机制,如果backgroundProcessorDelay为正值,那么子容器的一些任务会有后台线程帮忙处理,为负值,则由当前容器一并处理。这些任务都是周期性的比如例如重新加载等。
    // 为engine配置上Valve,设置container
    configureEngine(tomcat.getEngine());
    // 给这个service添加额外的connector,从这可以看出connector和service的关系是多对一
    // container和service是1对1
    for (Connector additionalConnector : this.additionalTomcatConnectors) {
        tomcat.getService().addConnector(additionalConnector);
    }
    // 准备一个context给engine,这里我们设置TomcatEmbeddedContext,这个是spring自己写的,然后配置好这个context的一些属性
    prepareContext(tomcat.getHost(), initializers);
    // 启动tomcat(即tomcat的容器被启动,但是connector没有启动)
    return getTomcatWebServer(tomcat);
}

根据上面的代码,我们发现其主要做了两件事情,第一件事就是把Connnctor(我们称之为连接器)对象添加到Tomcat中,第二件事就是configureEngine,这连接器我们勉强能理解(不理解后面会述说),那这个Engine是什么呢?我们查看tomcat.getEngine()的源码:

public Engine getEngine() {
    Service service = getServer().findServices()[0];
    if (service.getContainer() != null) {
        return service.getContainer();
    }
    Engine engine = new StandardEngine();
    engine.setName( "Tomcat" );
    engine.setDefaultHost(hostname);
    engine.setRealm(createDefaultRealm());
    service.setContainer(engine);
    return engine;
}

根据上面的源码,我们发现,原来这个Engine是容器,我们继续跟踪源码,找到Container接口。
http://image.winrains.cn/2019/11/20191105180857-af4b4.png
上图中,我们看到了4个子接口,分别是Engine,Host,Context,Wrapper。我们从继承关系上可以知道他们都是容器,Engine是最高级别的容器,其子容器是Host,Host的子容器是Context,Wrapper是Context的子容器,所以这4个容器的关系就是父子关系,也就是Engine>Host>Context>Wrapper。我们再看看Tomcat类的源码:

//部分源码,其余部分省略。
public class Tomcat {
    // 设置连接器
    public void setConnector(Connector connector) {
        Service service = getService();
        boolean found = false;
        for (Connector serviceConnector : service.findConnectors()) {
            if (connector == serviceConnector) {
                found = true;
            }
        }
        if (!found) {
            service.addConnector(connector);
        }
    }
    // 获取service
    public Service getService() {
        return getServer().findServices()[0];
    }
    // 设置Host容器
    public void setHost(Host host) {
        Engine engine = getEngine();
        boolean found = false;
        for (Container engineHost : engine.findChildren()) {
            if (engineHost == host) {
                found = true;
            }
        }
        if (!found) {
            engine.addChild(host);
        }
    }
    // 获取Engine容器
    public Engine getEngine() {
        Service service = getServer().findServices()[0];
        if (service.getContainer() != null) {
            return service.getContainer();
        }
        Engine engine = new StandardEngine();
        engine.setName("Tomcat");
        engine.setDefaultHost(hostname);
        engine.setRealm(createDefaultRealm());
        service.setContainer(engine);
        return engine;
    }
    // 获取server
    public Server getServer() {
        if (server != null) {
            return server;
        }
        System.setProperty("catalina.useNaming", "false");
        server = new StandardServer();
        initBaseDir();
        // Set configuration source
        ConfigFileLoader.setSource(new CatalinaBaseConfigurationSource(new File(basedir), null));
        server.setPort(-1);
        Service service = new StandardService();
        service.setName("Tomcat");
        server.addService(service);
        return server;
    }
    // 添加Context容器
    public Context addContext(Host host, String contextPath, String contextName,
            String dir) {
        silence(host, contextName);
        Context ctx = createContext(host, contextPath);
        ctx.setName(contextName);
        ctx.setPath(contextPath);
        ctx.setDocBase(dir);
        ctx.addLifecycleListener(new FixContextListener());
        if (host == null) {
            getHost().addChild(ctx);
        } else {
            host.addChild(ctx);
        }
    // 添加Wrapper容器
    public static Wrapper addServlet(Context ctx, String servletName, Servlet servlet) {
        // will do class for name and set init params
        Wrapper sw = new ExistingStandardWrapper(servlet);
        sw.setName(servletName);
        ctx.addChild(sw);
        return sw;
    }
}

阅读Tomcat的getServer()我们可以知道,Tomcat的最顶层是Server,Server就是Tomcat的实例,一个Tomcat一个Server;通过getEngine()我们可以了解到Server下面是Service,而且是多个,一个Service代表我们部署的一个应用,而且我们还可以知道,Engine容器,一个service只有一个;根据父子关系,我们看setHost()源码可以知道,host容器有多个;同理,我们发现addContext()源码下,Context也是多个;addServlet()表明Wrapper容器也是多个,而且这段代码也暗示了,其实Wrapper和Servlet是一层意思。另外我们根据setConnector源码可以知道,连接器(Connector)是设置在service下的,而且是可以设置多个连接器(Connector)。
根据上面分析,我们可以小结下:Tomcat主要包含了2个核心组件,连接器(Connector)和容器(Container),用图表示如下:
http://image.winrains.cn/2019/11/20191105180858-ba70f.png
一个Tomcat是一个Server,一个Server下有多个service,也就是我们部署的多个应用,一个应用下有多个连接器(Connector)和一个容器(Container),容器下有多个子容器,关系用图表示如下:
http://image.winrains.cn/2019/11/20191105180858-48436.png
Engine下有多个Host子容器,Host下有多个Context子容器,Context下有多个Wrapper子容器。

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.完成刷新.

作者:模范青蛙

来源:https://segmentfault.com/a/1190000020494692


版权声明:文末如注明作者和来源,则表示本文系转载,版权为原作者所有 | 本文如有侵权,请及时联系,承诺在收到消息后第一时间删除 | 如转载本文,请注明原文链接。
喜欢 (0)