SpringBoot启动源码浅析

文章目录

一. 前言

1. 相关文章

2. 说明

  • 本文SpringBoot源码解读使用的版本为2.3.9.RELEASE. 引入依赖 spring-boot-starter-web:2.3.9.RELEASE (此版本相对3.X可读性更强, 学习源码推荐使用此版本)
  • 本文会稍微提到SpringCloud, 使用的版本为 spring-cloud-context:2.2.7.RELEASE
  • 本文所有内容都是基于个人理解, 有疑问时请自行研读源码
  • Spring官方文档: https://spring.io/projects/spring-boot
  • SpringBoot官方参考文档: https://docs.spring.io/spring-boot/docs/current/reference/html/
  • 本文属性翻译中文都是瞎取名, 不要在意细节.
  • 本文属性翻译中文都是瞎取名, 不要在意细节.
  • 本文属性翻译中文都是瞎取名, 不要在意细节.

使用到的依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.9.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-context</artifactId>
            <version>2.2.7.RELEASE</version>
        </dependency>
    </dependencies>

二. 源码浅析

1. 入口

1.1 启动引导类

SpringBoot的项目启动从SpringApplication的run方法开始.

@SpringBootApplication
public class StudyApplication {
    public static void main(String[] args) {
        // 创建SpringApplication对象. 参数为主启动类
        SpringApplication springApplication = new SpringApplication(StudyApplication.class);
        // 执行run方法
        springApplication.run(args);
    }
}

启动代码也可以写成 SpringApplication.run(StudyApplication.class, args);

1.2 创建SpringApplication

跟踪SpringApplication的构造方法进入最终的构造器中

    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        // 初始化资源加载器, 默认为null
        this.resourceLoader = resourceLoader;
        Assert.notNull(primarySources, "PrimarySources must not be null");
        // 设置首要加载源. (后续本文都称sources和primarySources为加载源)
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
        // 推断web应用类型
        this.webApplicationType = WebApplicationType.deduceFromClasspath();
        // 设置初始化器
        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
        // 设置监听器. 该监听器用于监听ApplicationEvent事件
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        // 通过栈信息推断main方法的所在的启动类
        this.mainApplicationClass = deduceMainApplicationClass();
    }

构造器中做了以下几点

  • 设置首要加载源(后续本文都称sources和primarySources为加载源). 加载源类作为后续应用上下文扫描加载bean的入口
  • 确认web应用类型. 根据扫描reactive和servlet关联的类确认web应用类型.
    • 类型一共有三种: REACTIVE、SERVLET、NONE. 本项目引用了spring-boot-starter-web故为SERVLET应用
    • webApplicationType作用: 确定创建Environment的实现类型, 确认创建应用上下文的实现类型
  • 设置初始化器. 默认添加的初始化器如下图,源码说明如下
    • 调用getSpringFactoriesInstances方法, 传入要获取指定类型(这里为ApplicationContextInitializer)的bean集合
    • 首先通过SpringFactoriesLoader#loadFactoryNames方法获取META-INF/spring.factories下所有的接口及其实现类
    • 然后遍历获取指定类型(这里为ApplicationContextInitializer)的实现类名字列表, 反射创建bean, 将创建的bean加入初始化器列表
    • 拓展点: 可以手动添加自己需要的初始化器监听器等到META-INF/spring.factories下
  • 设置监听器. 默认添加的监听器如下图
    • 加载方式: 加载监听器的方式和初始化一样, 也是调用getSpringFactoriesInstances方法
    • 监听器作用: 监听器会监听ApplicationEvent方法, 处理其关注的ApplicationEvent事件
    • SpringCloud相关: SpringCloud项目启动时也会添加多个监听器, 其中一个重要的监听器为BootstrapApplicationListener. 详情可查询系列文章 SpringCloud父子容器源码浅析
    • SpringApplicationEvent事件类型: SpringApplicationEvent是ApplicationEvent的子类, 在SpringBoot启动中发布的SpringApplicationEvent类型如下(按照时间顺序排列):
      • ApplicationStartingEvent 应用开始启动事件
      • ApplicationEnvironmentPreparedEvent 环境已准备好事件
      • ApplicationContextInitializedEvent 应用上下文创建并初始化完成事件
      • ApplicationPreparedEvent 应用上下文准备完成事件 (应用上下文加载完,在调用refreshContext之前)
      • ApplicationStartedEvent 应用程序已启动事件
      • ApplicationReadyEvent 应用程序已就绪事件
      • ApplicationFailedEvent 应用程序启动失败事件
  • 通过栈信息推断main方法的所在的启动类(逻辑简单, 不展开)

在这里插入图片描述

2. 执行SpringApplication的run()方法

    public ConfigurableApplicationContext run(String... args) {
        // 计时器. 开始计时
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        // 设置系统属性“java.awt.headless”的值, 默认为true.用于运行headless服务器, 进行简单的图像处理(不展开)
        // 多用于在缺少显示屏、键盘或者鼠标时的系统配置, 很多监控工具如jconsole需要将该值设置为true
        configureHeadlessProperty();
        // 2.1 获取运行监听管理器
        SpringApplicationRunListeners listeners = getRunListeners(args);
        // 发布ApplicationStartingEvent事件
        listeners.starting();
        try {
            // 初始化默认应用参数类(不展开)
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            // 2.2 环境构建 (SpringCloud的父子容器创建入口). (发布ApplicationEnvironmentPreparedEvent事件)
            ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
            // 设置要忽略的bean的参数spring.beaninfo.ignore(不展开)
            configureIgnoreBeanInfo(environment);
            // 打印出banner.txt并返回PrintedBanner打印类(不展开)
            Banner printedBanner = printBanner(environment);
            // 2.3 创建应用上下文(或者叫容器/IOC容器)
            context = createApplicationContext();
            // 获取异常报告器(不展开)
            exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
                    new Class[] { ConfigurableApplicationContext.class }, context);
            // 2.4 初始化应用上下文 (发布ApplicationContextInitializedEvent和ApplicationPreparedEvent事件)
            prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            // 2.5 刷新应用上下文 (含添加JVM关闭时回调的钩子, 以便优雅的关闭运行的应用)
            refreshContext(context);
            // 2.6 应用上下文后处理(空方法)
            afterRefresh(context, applicationArguments);
            // 停止计时
            stopWatch.stop();
            if (this.logStartupInfo) {
                // 输出日志记录执行主类名、启动耗时(不展开)
                new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
            }
            // 使用应用上下文发布ApplicationStartedEvent事件
            listeners.started(context);
            // 执行ApplicationRunner和CommandLineRunner
            callRunners(context, applicationArguments);
        } catch (Throwable ex) {
            // 处理启动异常 (发布ApplicationFailedEvent事件)
            handleRunFailure(context, ex, exceptionReporters, listeners);
            throw new IllegalStateException(ex);
        }

        try {
            // 使用应用上下文发布ApplicationReadyEvent事件
            listeners.running(context);
        } catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, null);
            throw new IllegalStateException(ex);
        }
        return context;
    }

2.1 获取运行监听管理器

SpringApplicationRunListeners 的作用是发布特定的事件, 这里我们管它为运行监听管理器
一般情况下, SpringApplicationRunListeners 中仅有一个EventPublishingRunListener元素. 下面看源码了解其创建过程

	private SpringApplicationRunListeners getRunListeners(String[] args) {
		Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
		// 其中getSpringFactoriesInstances方法仅获取到默认的运行监听器EventPublishingRunListener
		return new SpringApplicationRunListeners(logger,
				getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
	}

SpringApplicationRunListener的默认实现类如下图
在这里插入图片描述

SpringApplicationRunListeners最终结构如下:
在这里插入图片描述

SpringApplicationRunListeners主要代码如下.

class SpringApplicationRunListeners {
	private final Log log;
	// 运行监听器列表(一般仅有EventPublishingRunListener一个元素)
	private final List<SpringApplicationRunListener> listeners;

	SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) {
		this.log = log;
		this.listeners = new ArrayList<>(listeners);
	}

	void starting() {
		// 遍历运行监听器执行其starting方法
		for (SpringApplicationRunListener listener : this.listeners) {
			listener.starting();
		}
	}
	void environmentPrepared(ConfigurableEnvironment environment) {...}
	void contextPrepared(ConfigurableApplicationContext context) {...}
	void contextLoaded(ConfigurableApplicationContext context) {...}
	void started(ConfigurableApplicationContext context) {...}
	void running(ConfigurableApplicationContext context) {...}
	void failed(ConfigurableApplicationContext context, Throwable exception) {...}
	//...
}

SpringApplicationRunListeners#starting遍历的SpringApplicationRunListener仅有EventPublishingRunListener, EventPublishingRunListener的主要代码如下. 不同方法发布着不同的SpringEvent事件

public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
	private final SpringApplication application;
	private final String[] args;
	private final SimpleApplicationEventMulticaster initialMulticaster;
	
	public EventPublishingRunListener(SpringApplication application, String[] args) {
		this.application = application;
		this.args = args;
		// 创建一个广播器. 实际发布事件的对象
		this.initialMulticaster = new SimpleApplicationEventMulticaster();
		for (ApplicationListener<?> listener : application.getListeners()) {
			// 将SpringApplication创建时获取的ApplicationListener添加到广播器中
			this.initialMulticaster.addApplicationListener(listener);
		}
	}

	public void starting() {
		// 使用广播器发布ApplicationStartingEvent事件
		this.initialMulticaster.multicastEvent(
			new ApplicationStartingEvent(this.application, this.args));
	}
	public void environmentPrepared(ConfigurableEnvironment environment) {
		this.initialMulticaster.multicastEvent(
			new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
	}
	public void contextPrepared(ConfigurableApplicationContext context) {
		this.initialMulticaster.multicastEvent(
			new ApplicationContextInitializedEvent(this.application, this.args, context));
	}
	public void contextLoaded(ConfigurableApplicationContext context) {
		//...
		this.initialMulticaster.multicastEvent(
			new ApplicationPreparedEvent(this.application, this.args, context));
	}
	public void started(ConfigurableApplicationContext context) {
		context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context));
		AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
	}
	public void running(ConfigurableApplicationContext context) {
		context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context));
		AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
	}
	public void failed(ConfigurableApplicationContext context, Throwable exception) {
		ApplicationFailedEvent event = new ApplicationFailedEvent(this.application, this.args, context, exception);
		//...
	}
	//...
}

由源码可知, 但执行SpringApplicationRunListeners.starting()方法时, 实际是调用EventPublishingRunListener的广播器发布ApplicationStartingEvent事件.
multicastEvent方法会筛选出SpringApplication添加的ApplicationListener监听器中 监听该事件的监听器, 执行onApplicationEvent方法接收事件处理. 默认都是同步方式执行时间发布和监听器处理的(广播器内的线程池默认为空)

	public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
		Executor executor = getTaskExecutor();
		// 获取监听该事件的监听器遍历
		for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
			if (executor != null) {
				executor.execute(() -> invokeListener(listener, event));
			} else {
			    // 默认走同步调用
				invokeListener(listener, event);
			}
		}
	}
	
	protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
		ErrorHandler errorHandler = getErrorHandler();
		if (errorHandler != null) {
			try {
				doInvokeListener(listener, event);
			} catch (Throwable err) {
				errorHandler.handleError(err);
			}
		} else {
			doInvokeListener(listener, event);
		}
	}
	
	private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
		try {
		    // 执行监听器的onApplicationEvent方法
			listener.onApplicationEvent(event);
		}
	}

2.2 环境构建

    private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
                                                       ApplicationArguments applicationArguments) {
        // 根据web应用类型创建Environment对象. 这里是servlet类型故创建出StandardServletEnvironment
        ConfigurableEnvironment environment = getOrCreateEnvironment();
        // 配置环境. 配置propertySource和activeProfiles
        configureEnvironment(environment, applicationArguments.getSourceArgs());
        // environment添加一个名字为configurationProperties的PropertySource
        ConfigurationPropertySources.attach(environment);
        // 环境准备完成, 发布ApplicationEnvironmentPreparedEvent事件.
        // (SpringCloud会执行BootstrapApplicationListener. SpringCloud父子容器代码入口)
        listeners.environmentPrepared(environment);
        // 环境与当前应用程序绑定 (实际上SpringApplication和environment并没有绑定, 源码较深暂不深究)
        bindToSpringApplication(environment);
        // 转换为当前web应用类型的environment (SpringCloud父容器环境准备时会执行内部代码块, 子容器直接跳过)
        if (!this.isCustomEnvironment) {
            environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
                    deduceEnvironmentClass());
        }
        // environment可能发生变化, 重新再来一遍(确保configurationProperties属性源在第一个位置? 之前的attach有什么作用?)
        ConfigurationPropertySources.attach(environment);
        return environment;
    }

    protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
    	// 设置属性类型转换器
        if (this.addConversionService) {
            ConversionService conversionService = ApplicationConversionService.getSharedInstance();
            environment.setConversionService((ConfigurableConversionService) conversionService);
        }
        // 配置属性源 (默认没有执行任何操作)
        configurePropertySources(environment, args);
        // 配置profiles
        configureProfiles(environment, args);
    }

SpringApplication#configureEnvironment和ConfigurationPropertySources#attach方法都是给Environment添加PropertySource. 添加PropertySource的具体过程可查看 3.1 Environment添加PropertySource过程

listeners.environmentPrepared(environment);中会发布出ApplicationEnvironmentPreparedEvent事件. 若是SpringCloud项目, 则该事件会被BootstrapApplicationListener监听处理, 开始父容器的创建, 具体过程可查看 系列文章-SpringCloud父子容器源码浅析

2.3 创建应用上下文

应用上下文也经常被叫做容器, 这里的应用上下文也叫做Spring的IOC容器. 常见的应用上下文见 3.3 应用上下文

    protected ConfigurableApplicationContext createApplicationContext() {
        Class<?> contextClass = this.applicationContextClass;
        if (contextClass == null) {
            try {
                switch (this.webApplicationType) {
                    case SERVLET:
                        // servlet类型的web应用使用AnnotationConfigServletWebServerApplicationContext上下文
                        contextClass = Class.forName("org.springframework.boot."
                                + "web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
                        break;
                    case REACTIVE:
                        contextClass = Class.forName("org.springframework."
                                + "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";);
                        break;
                    default:
                        // 普通Spring项目使用AnnotationConfigApplicationContext上下文
                        contextClass = Class.forName("org.springframework.context."
                                + "annotation.AnnotationConfigApplicationContext");
                }
            } catch (ClassNotFoundException ex) {
                throw new IllegalStateException(
                        "Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
            }
        }
        // 反射创建出应用上下文对象
        return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
    }

这里为SERVLET类型的web应用类型, 故创建出的上下文为AnnotationConfigServletWebServerApplicationContext

以下为AnnotationConfigServletWebServerApplicationContext的继承类及字段
在这里插入图片描述

重要的字段如下:

  • environment: 容器环境. 这里的实现类为StandardServletEnvironment
  • beanFactoryPostProcessors: beanFactory的后置处理器列表
  • parent: 父容器对象(SpringCloud时会有该值)
  • beanFactory: bean工厂, 管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系. 这里的实现类为DefaultListableBeanFactory. 其继承的类及字段如下图
    • beanPostProcessors: bean的后置处理器列表
    • singletonObjects: 单例对象的缓存. bean名称 -> bean实例
    • registeredSingletons: 已注册的单例的bean名称列表.按注册顺序排序(LinkedHashSet类型保证有序且不重复)
    • beanDefinitionMap: bean定义的map. bean名称 -> bean定义
    • beanDefinitionNames: bean定义名称列表, 按注册顺序排列
      在这里插入图片描述

2.4 初始化应用上下文

后续的流程只关注SpringBoot的主线逻辑, 去掉SpringCloud的依赖, 不再提及SpringCloud
后续的流程只关注SpringBoot的主线逻辑, 去掉SpringCloud的依赖, 不再提及SpringCloud
后续的流程只关注SpringBoot的主线逻辑, 去掉SpringCloud的依赖, 不再提及SpringCloud

    private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
                                SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments,
                                Banner printedBanner) {
        // 为应用上下文绑定环境
        context.setEnvironment(environment);
        // 应用上下文的后置处理(不展开). 仅为上下文的beanFactory添加了ConversionService
        postProcessApplicationContext(context);
        // 执行SpringApplication的初始化器的initialize方法.
        // SpringCloud的AncestorInitializer在这里执行完成父子容器绑定 (最后一次提及SpringCloud, 后续不再关注SpringCloud)
        applyInitializers(context);
        // 发布ApplicationContextInitializedEvent事件
        listeners.contextPrepared(context);
        // 打印启动使用的Profile参数
        if (this.logStartupInfo) {
            logStartupInfo(context.getParent() == null);
            logStartupProfileInfo(context);
        }

        // 获取上下文的bean工厂, 实现类为DefaultListableBeanFactory.
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        // beanFactory缓存单例bean springApplicationArguments和springBootBanner
        beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
        if (printedBanner != null) {
            beanFactory.registerSingleton("springBootBanner", printedBanner);
        }

        // beanFactory设置allowBeanDefinitionOverriding的值. 这里设置为false
        if (beanFactory instanceof DefaultListableBeanFactory) {
            ((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
        }
        // 上下文添加惰性初始化beanFactory后置处理器. 这里不添加
        if (this.lazyInitialization) {
            context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
        }

        // 获取所有的加载源. 例如SpringApplication.run(StudyApplication.class, args), StudyApplication就是加载源
        Set<Object> sources = getAllSources();
        Assert.notEmpty(sources, "Sources must not be empty");
        // 重点: 加载 加载源, 为每个加载源构建bean定义对象, 缓存到beanFactory中(存储到beanDefinitionMap和beanDefinitionNames)
        // 此方法较简单, 不展开, 可自行看源码
        load(context, sources.toArray(new Object[0]));
        // 为上下文添加SpringApplication的所有监听器, 并使用SpringApplication广播器发布ApplicationPreparedEvent事件
        // 注: 后续发布的ApplicationStartedEvent和ApplicationReadyEvent事件都是通过上下文来发布的
        listeners.contextLoaded(context);
    }

    protected void applyInitializers(ConfigurableApplicationContext context) {
        for (ApplicationContextInitializer initializer : getInitializers()) {
            Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
                    ApplicationContextInitializer.class);
            Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
            // 执行初始化器的初始化方法
            initializer.initialize(context);
        }
    }

主要内容:

  1. 执行SpringApplication的初始化器的initialize方法 (SpringCloud的AncestorInitializer在这里执行完成父子容器绑定)
  2. 发布ApplicationContextInitializedEvent事件
  3. beanFactory添加单例bean和设置属性
  4. 加载 加载源, 为每个加载源构建bean定义对象, 缓存到beanFactory中 (SpringBoot自动配置的入口)
  5. 发布ApplicationPreparedEvent事件

2.5 刷新应用上下文

    private void refreshContext(ConfigurableApplicationContext context) {
        // 添加JVM关闭时回调的钩子, 以便优雅的关闭运行的应用. 这里默认是会执行的
        if (this.registerShutdownHook) {
            try {
                context.registerShutdownHook();
            }
            catch (AccessControlException ex) {
                // Not allowed in some environments.
            }
        }
        // 执行刷新
        refresh((ApplicationContext) context);
    }

    public void registerShutdownHook() {
        if (this.shutdownHook == null) {
            // 创建一个线程作为钩子
            this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
                @Override
                public void run() {
                    synchronized (startupShutdownMonitor) {
                        // 执行上下文的doClose()方法, 完成容器的关闭
                        doClose();
                    }
                }
            };
            // 将创建的线程作为JVM关闭时调用的钩子. 待JVM正常关闭(如执行System.exit(0))会调用钩子
            Runtime.getRuntime().addShutdownHook(this.shutdownHook);
        }
    }

	protected void refresh(ConfigurableApplicationContext applicationContext) {
		// 使用应用上下文执行刷新方法. 最终执行到父类AbstractApplicationContext#refresh方法
		applicationContext.refresh();
	}

	
	

添加JVM关闭钩子, 以便JVM正常关闭时优雅的关闭容器. 例如执行System.exit(0)可正常的关闭JVM

执行AbstractApplicationContext#refresh. 这里是最核心的部分, 也是耗时最长的位置

    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 2.5.1 刷新前预处理
            // a.清空扫描器缓存 b.设置上下文active为激活状态 c.暂存监听器到earlyApplicationListeners
            prepareRefresh();

            // 2.5.2 获取beanFactory
            // a.设置上下文的refreshed标记为true b.为beanFactory设置序列化id c.返回beanFactory
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 2.5.3 beanFactory预处理
            // a.对beanFactory的各种功能进行填充 b.添加bean的后置处理器、要忽略的*Aware接口、可注入的bean c.添加环境相关的bean到容器
            prepareBeanFactory(beanFactory);

            try {
                // 2.5.4 beanFactory再次处理
                // a.添加bean的后置处理器和其下忽略的接口ServletContextAware c.添加作用域和web相关的四个可注入的bean
                postProcessBeanFactory(beanFactory);

                // 2.5.5 调用BeanFactoryPostProcessor和其子类的后置处理方法(含解析@Configuration、@Bean等注解)
                invokeBeanFactoryPostProcessors(beanFactory);

                // 2.5.6 注册bean后置处理器BeanPostProcessor
                registerBeanPostProcessors(beanFactory);

                // 2.5.7 初始化国际化处理器MessageSource
                initMessageSource();

                // 2.5.8 初始化事件广播器
                initApplicationEventMulticaster();

                // 2.5.9 为上下文设置themeSource和webServer
                onRefresh();

                // 2.5.10 为上下文的事件广播器添加监听器
                registerListeners();

                // 2.5.11 完成beanFactory的初始化(含实例化非惰性单例bean)
                // a.设置beanFactory临时的类加载器等 b.冻结所有bean定义 c.实例化所有剩余的非惰性单例bean
                finishBeanFactoryInitialization(beanFactory);

                // 2.5.12 上下文完成刷新
                // a.清除上下文资源缓存 b.为上下文添加生命周期处理器并执行刷新过程 c.发布ContextRefreshedEvent事件
                finishRefresh();
            } catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + ex);
                }

                // 销毁所有的单例bean及其他缓存
                destroyBeans();

                // beanFactory的序列化id置为空, 设置active标志为false
                cancelRefresh(ex);
                throw ex;
            } finally {
                // 重置Spring的公共反射元数据缓存
                resetCommonCaches();
            }
        }
    }


具体内容:
2.5.1 刷新前预处理
        a.清空扫描器缓存 b.设置上下文active为激活状态 c.暂存监听器到earlyApplicationListeners
2.5.2 获取beanFactory
        a.设置上下文的refreshed标记为true b.为beanFactory设置序列化id c.返回beanFactory
2.5.3 beanFactory预处理
        a.对beanFactory的各种功能进行填充 b.添加bean的后置处理器和要忽略的*Aware接口 c.添加环境相关的bean到容器
2.5.4 beanFactory再次处理
         a.添加bean的后置处理器 b.添加要忽略的接口ServletContextAware c.添加添加作用域和ResolvableDependency
2.5.5 调用BeanFactoryPostProcessor和其子类的后置处理方法
        (含解析@Configuration、@ComponentScan、@ComponentScans、@Import、@Bean注解)
2.5.6 注册bean后置处理器BeanPostProcessor
2.5.7 初始化国际化处理器MessageSource
2.5.8 初始化事件广播器
2.5.9 为上下文设置themeSource和webServer
2.5.10 为上下文的事件广播器添加监听器
2.5.11 完成beanFactory的初始化(含实例化非惰性单例bean)
        a.设置beanFactory临时的类加载器等 b.冻结所有bean定义 c.实例化所有剩余的非惰性单例bean
2.5.12 上下文完成刷新
        a.清除上下文资源缓存 b.为上下文添加生命周期处理器并执行刷新过程 c.发布ContextRefreshedEvent

下面看下里面具体方法做了什么

2.5.1 刷新前预处理

执行AnnotationConfigServletWebServerApplicationContext#prepareRefresh

	protected void prepareRefresh() {
		// 扫描器 清除本地元数据缓存(如果有的话),删除所有缓存的类元数据
		this.scanner.clearCache();
		// 执行父类AbstractApplicationContext#prepareRefresh
		super.prepareRefresh();
	}

	// 执行父类AbstractApplicationContext#prepareRefresh
	protected void prepareRefresh() {
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		// 设置active为激活状态
		this.active.set(true);

		if (logger.isDebugEnabled()) {//...}

		// 初始化上下文环境中所有的占位符属性源(debug发现其实不满足条件什么都没做)
		initPropertySources();

		// 验证指定的属性是否存在, 若存在且解析为空值则抛出异常.
		// (debug发现requiredProperties为空不满足条件什么都没做)
		getEnvironment().validateRequiredProperties();

		if (this.earlyApplicationListeners == null) {
			// 刷新前暂存应用监听器(为什么这么做?). 启动时默认执行这里
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		} else {
			// 使用earlyApplicationListeners 重置当前的监听器列表. 
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

a.清空扫描器缓存
b.设置上下文active为激活状态
c.暂存监听器到earlyApplicationListeners

2.5.2 获取beanFactory

执行AbstractApplicationContext#obtainFreshBeanFactory

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		// 执行父类GenericApplicationContext#refreshBeanFactory
		refreshBeanFactory();
		// 直接返回beanFactory
		return getBeanFactory();
	}

	// 执行父类GenericApplicationContext#refreshBeanFactory
	protected final void refreshBeanFactory() throws IllegalStateException {
		// 设置上下文的refreshed标记为true
		if (!this.refreshed.compareAndSet(false, true)) {
			throw new IllegalStateException(
				"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
		}
		// 设置beanFactory的序列化id为"application"
		this.beanFactory.setSerializationId(getId());
	}
	

a.设置上下文的refreshed标记为true
b.为beanFactory设置序列化id
c.返回beanFactory

2.5.3 beanFactory预处理

执行AbstractApplicationContext#prepareBeanFactory

	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 设置类加载器、Bean表达式解析器、属性编辑注册器 (本文都是瞎取名, 不要在意细节)
		beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// 注册一个ApplicationContextAwareProcessor的bean后置处理器, 注册要忽略的六个Aware接口 
		// (该bean后置处理器就是用于注入这些Aware接口的属性bean的, XxxAware作用就是将xxx的bean注入实现类中)
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// 注册四个可注入的bean(XxxAware的可注入的bean就是xxx)
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// 添加一个ApplicationListenerDetector的bean后置处理器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// 存在loadTimeWeaver的bean时, 添加bean后置处理器LoadTimeWeaverAwareProcessor和临时的类加载器(默认不执行)
		if (beanFactory.containsBean("loadTimeWeaver")) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// 添加环境相关的几个bean到容器中
		if (!beanFactory.containsLocalBean("environment")) {
			beanFactory.registerSingleton("environment", getEnvironment());
		}
		if (!beanFactory.containsLocalBean("systemProperties")) {
			beanFactory.registerSingleton("systemProperties", getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean("systemEnvironment")) {
			beanFactory.registerSingleton("systemEnvironment", getEnvironment().getSystemEnvironment());
		}
	}

a.对beanFactory的各种功能进行填充(解析器, 属性编辑注册器等)
b.注册bean的后置处理器ApplicationContextAwareProcessor及注册忽略其解析的六个Aware接口, 注册四个可注入的bean
c.添加环境相关的几个bean到容器

补充1:

  • beanFactory的containsLocalBean方法: 查找当前bean工厂是否包含该bean或其bean的定义
  • beanFactory的containsBean方法: 查找当前bean工厂是否包含该bean或其bean的定义, 当前bean工厂没有则再递归其父bean工厂去查找;

补充2: 注意BeanFactoryPostProcessor与BeanPostProcessor是不同的.
更多请查看: 3.4 BeanFactoryPostProcessor与BeanPostProcessor的区别

2.5.4 beanFactory再次处理

执行AnnotationConfigServletWebServerApplicationContext#postProcessBeanFactory方法

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 执行父类ServletWebServerApplicationContext.postProcessBeanFactory
        super.postProcessBeanFactory(beanFactory);
        // basePackages不为空则扫描包(默认不执行)
        if (this.basePackages != null && this.basePackages.length > 0) {
            this.scanner.scan(this.basePackages);
        }
        // annotatedClasses不为空则注册添加(默认不执行)
        if (!this.annotatedClasses.isEmpty()) {
            this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
        }
    }

    // 执行父类ServletWebServerApplicationContext.postProcessBeanFactory
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 添加bean的后置处理器WebApplicationContextServletContextAwareProcessor
        beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
        // 添加依赖注入时要忽略的接口ServletContextAware
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
        // 为beanFactory添加作用域和web相关的四个可注入的bean
        registerWebApplicationScopes();
    }

a.添加bean的后置处理器WebApplicationContextServletContextAwareProcessor和其下要忽略的ServletContextAware接口
b.添加添加作用域和web相关的四个可注入的bean(ServletRequest, ServletResponse, HttpSession, WebRequest)

2.5.5 调用BeanFactoryPostProcessor和其子类的后置处理方法(含解析@Configuration、@Bean等注解)

执行父类AbstractApplicationContext.invokeBeanFactoryPostProcessors

    // 执行父类AbstractApplicationContext.invokeBeanFactoryPostProcessors
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 执行PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

        // 存在loadTimeWeaver的bean时, 添加bean后置处理器LoadTimeWeaverAwareProcessor和临时的类加载器(默认不执行)
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }

    // 执行PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
    public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        Set<String> processedBeans = new HashSet<>();

        // 1. 先执行上下文中所有BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
        // 注: BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                } else {
                    regularPostProcessors.add(postProcessor);
                }
            }

            // 2. 执行beanFactory下所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            // 重要: 在这里执行了最重要的一个后置处理器ConfigurationClassPostProcessor. 解析加了@Configuration的配置类,
            // 还会解析@ComponentScan、@ComponentScans注解扫描的包, 以及解析@Import等注解
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // 3. 执行beanFactory下所有实现Ordered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                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);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // 3. 执行beanFactory下其他的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,
            // 直到没有其他BeanDefinitionRegistryPostProcessors出现为止
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (!processedBeans.contains(ppName)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
            }

            // 4. 执行上下文和beanFactory中所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            // 5. 执行上下文中所有普通的BeanFactoryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            // 直接调用postProcessBeanFactory方法(默认不执行此代码块)
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }


        // 分类获取beanFactory中实现了PriorityOrdered, 实现了Ordered, 和其余的BeanFactoryPostProcessor
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            if (processedBeans.contains(ppName)) {
                // 已执行的bean则跳过, 这里跳过属于BeanDefinitionRegistryPostProcessor的BeanFactoryPostProcessor
            } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            } else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // 6. 执行beanFactory下实现了PriorityOrdered的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // 7. 执行beanFactory下实现了Ordered的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // 8. 执行beanFactory下其他的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        beanFactory.clearMetadataCache();
    }

	private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
		for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
		    // 执行postProcessBeanDefinitionRegistry
			postProcessor.postProcessBeanDefinitionRegistry(registry);
		}
	}
	
	private static void invokeBeanFactoryPostProcessors(
			Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
		for (BeanFactoryPostProcessor postProcessor : postProcessors) {
		    // 执行postProcessBeanFactory
			postProcessor.postProcessBeanFactory(beanFactory);
		}
	}

BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口
BeanFactoryPostProcessor含有方法postProcessBeanFactory (后置处理bean工厂)
BeanDefinitionRegistryPostProcessor含有方法postProcessBeanDefinitionRegistry (后置处理bean定义注册)
这里调用了一个很重要的bean工厂的后置处理器ConfigurationClassPostProcessor. 它会解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解. 想进一步了解的可以查看文章 ConfigurationClassPostProcessor —— Spring中最!最!最!重要的后置处理器!没有之一!!!

a.执行上下文中BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
b.执行beanFactory中BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry (按实现注解PriorityOrdered,实现注解Ordered,其他 的顺序执行)
c.执行上下文和beanFactory中BeanDefinitionRegistryPostProcessor#postProcessBeanFactory
d.执行上下文中普通的BeanFactoryPostProcessor#postProcessBeanFactory
e.执行beanFactory中普通BeanFactoryPostProcessor#postProcessBeanFactory (按实现注解PriorityOrdered,实现注解Ordered,其他 的顺序执行)

注:

  • 一般情况下, bean定义由ConfigurationClassPostProcessor和MapperScannerConfigurer两个BeanDefinitionRegistryPostProcessor完成注册的, 大部分的bean定义都是由ConfigurationClassPostProcessor注册的
  • 注册后的bean定义, 在AbstractApplicationContext#finishBeanFactoryInitialization中创建出单例bean
2.5.6 注册bean后置处理器BeanPostProcessor

注意BeanFactoryPostProcessor与BeanPostProcessor是不同的.
更多请查看: 3.4 BeanFactoryPostProcessor与BeanPostProcessor的区别

执行AbstractApplicationContext#registerBeanPostProcessors


    // 执行AbstractApplicationContext#registerBeanPostProcessors
    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }

    // 执行PostProcessorRegistrationDelegate#registerBeanPostProcessors
    public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        // 获取BeanPostProcessor类型的的所有后置处理器名称
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        // a. 添加一个bean后置处理器BeanPostProcessorChecker(作用: 当一个bean没有被任一BeanPostProcessor处理时输出日志)
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // b. 分类获取beanFactory中实现了PriorityOrdered, 实现了Ordered, 和其余的BeanPostProcessor. 注册到beanFactory中
        // 另外按顺序记录下属于MergedBeanDefinitionPostProcessor的BeanPostProcessor
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            } else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // b1. 注册所有实现PriorityOrdered的BeanPostProcessor
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        // b2. 注册所有实现Ordered的BeanPostProcessor
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String ppName : orderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);

        // b3. 注册其他的BeanPostProcessor
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        for (String ppName : nonOrderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

        // c.重新注册属于MergedBeanDefinitionPostProcessor的BeanPostProcessor (重新注册为了排序到最后面)
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        // d.重新注册ApplicationListenerDetector这个后置处理器 (重新注册为了排序到最后面)
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

    private static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
        for (BeanPostProcessor postProcessor : postProcessors) {
            // 将beanPostProcessor注册到beanFactory中
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }


a.添加一个bean后置处理器BeanPostProcessorChecker
b.分类获取beanFactory中实现了PriorityOrdered, 实现了Ordered, 和其余的BeanPostProcessor. 注册到beanFactory中
c.重新注册属于MergedBeanDefinitionPostProcessor的BeanPostProcessor
d.重新注册ApplicationListenerDetector这个后置处理器

2.5.7 初始化国际化处理器MessageSource

执行AbstractApplicationContext#initMessageSource

    protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        // 判断beanFactory是否已存在messageSource的bean(默认是不存在的)
        if (beanFactory.containsLocalBean("messageSource")) {
            // 设置messageSource到上下文中
            this.messageSource = beanFactory.getBean("messageSource", MessageSource.class);
            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
                HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
                if (hms.getParentMessageSource() == null) {
                    // 绑定父子上下文中messageSource的父子关系
                    hms.setParentMessageSource(getInternalParentMessageSource());
                }
            }
            if (logger.isTraceEnabled()) {
                logger.trace("Using MessageSource [" + this.messageSource + "]");
            }
        } else {
            // 创建一个新的MessageSource
            DelegatingMessageSource dms = new DelegatingMessageSource();
            // 绑定父子上下文中messageSource的父子关系
            dms.setParentMessageSource(getInternalParentMessageSource());
            // 设置到上下文中
            this.messageSource = dms;
            // 注册bean到beanFactory中
            beanFactory.registerSingleton("messageSource", this.messageSource);
            if (logger.isTraceEnabled()) {
                logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
            }
        }
    }
2.5.8 初始化事件广播器

执行AbstractApplicationContext#initApplicationEventMulticaster
注意: 这里是设置上下文和beanFactory的事件广播器, 与SpringApplication的事件广播器是没有关系的

    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        // 判断beanFactory是否已存在applicationEventMulticaster的bean(默认是不存在的)
        if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
            // 设置applicationEventMulticaster到上下文中
            this.applicationEventMulticaster =
                    beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
            if (logger.isTraceEnabled()) {
                logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        } else {
            // 创建新的时间广播器, 设置到上下文中
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            // 注册bean到beanFactory中
            beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
            if (logger.isTraceEnabled()) {
                logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
                        "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
            }
        }
    }
2.5.9 为上下文设置themeSource和webServer

    // 执行ServletWebServerApplicationContext#onRefresh
    protected void onRefresh() {
        // 执行GenericWebApplicationContext#onRefresh
        super.onRefresh();
        try {
            // 创建webServer
            createWebServer();
        }
        catch (Throwable ex) {
            throw new ApplicationContextException("Unable to start web server", ex);
        }
    }

    // 执行org.springframework.web.context.support.GenericWebApplicationContext#onRefresh
    protected void onRefresh() {
        // 为上下文设置主题源 ThemeSource
        this.themeSource = UiApplicationContextUtils.initThemeSource(this);
    }

    private void createWebServer() {
        // 获取应用上下文中的webServer(默认不存在)
        WebServer webServer = this.webServer;
        // 获取应用上下文中的Servlet上下文(默认不存在)
        ServletContext servletContext = getServletContext();
        if (webServer == null && servletContext == null) {
            ServletWebServerFactory factory = getWebServerFactory();
            // 创建出webServer实例并设置到上下文中
            this.webServer = factory.getWebServer(getSelfInitializer());
            // 为beanFactory注册webServer优雅关闭的bean
            getBeanFactory().registerSingleton("webServerGracefulShutdown",
                    new WebServerGracefulShutdownLifecycle(this.webServer));
            // 为beanFactory注册webServer启停的bean
            getBeanFactory().registerSingleton("webServerStartStop",
                    new WebServerStartStopLifecycle(this, this.webServer));
        } else if (servletContext != null) {
            try {
                getSelfInitializer().onStartup(servletContext);
            } catch (ServletException ex) {
                throw new ApplicationContextException("Cannot initialize servlet context", ex);
            }
        }
        // 初始化上下文Environment中名为servletContextInitParams的属性源
        initPropertySources();
    }


2.5.10 为上下文的事件广播器添加监听器

执行AbstractApplicationContext#registerListeners

    protected void registerListeners() {
        // 为上下文的事件广播器添加 上下文中的应用监听器
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }

        // 为上下文的事件广播器添加 beanFactory中的监听器bean的名字(先不添加bean, 待后置处理bean后再添加)
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // 发布早期的应用程序事件 (默认earlyApplicationEvents为空, 不执行发布)
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }
2.5.11 完成beanFactory的初始化(含实例化非惰性单例bean)

执行AbstractApplicationContext#finishBeanFactoryInitialization
重点: 在这里实例化剩余的所有的非惰性的单例bean

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 如果beanFactory中包含conversionService的bean且类型符合, 则重置beanFactory的conversionService (默认不包含)
        if (beanFactory.containsBean("conversionService") &&
                beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
            beanFactory.setConversionService(beanFactory.getBean("conversionService", ConversionService.class));
        }

        // 如果没有内嵌属性值解析器, 则添加 (默认不执行)
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }

        // 如果有LoadTimeWeaverAware的bean名字, 则创建出这些bean (默认没有)
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

        // 置空临时的类加载器
        beanFactory.setTempClassLoader(null);

        // 冻结所有bean定义, 已注册的bean定义不会被修改或进一步后处理
        beanFactory.freezeConfiguration();

        // 实例化所有剩余的非惰性单例bean(非延迟加载的bean)
        beanFactory.preInstantiateSingletons();
    }

beanFactory.preInstantiateSingletons()中实例化所有剩余的非惰性单例bean. 待有空时再浅析下这块的源码

2.5.12 完成上下文刷新

进入AbstractApplicationContext#finishRefresh

    protected void finishRefresh() {
        // 清除上下文资源缓存(例如扫描ASM元数据)
        clearResourceCaches();

        // 为上下文添加生命周期处理器
        initLifecycleProcessor();

        // 生命周期处理器刷新过程(例如webServerStartStop执行启动start处理)
        getLifecycleProcessor().onRefresh();

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

        // 视图器注册上下文(作用未了解)
        LiveBeansView.registerApplicationContext(this);
    }

    // 执行AbstractApplicationContext#initLifecycleProcessor
    protected void initLifecycleProcessor() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		// 判断beanFactory中是否有lifecycleProcessor的bean或其定义 (默认是有的)
		if (beanFactory.containsLocalBean("lifecycleProcessor")) {
		    // 设置lifecycleProcessor到上下文中
			this.lifecycleProcessor = beanFactory.getBean("lifecycleProcessor", LifecycleProcessor.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
			}
		} else {
		    // 没有则创建一个lifecycleProcessor, 设置到上下文中并注册到beanFactory中
			DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
			defaultProcessor.setBeanFactory(beanFactory);
			this.lifecycleProcessor = defaultProcessor;
			beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
						"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
			}
		}
	}

2.6 应用上下文后处理

	protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) {
	}

空实现方法
作用?
可以创建一个自己的SpringApplication继承SpringApplication, 重写afterRefresh方法用来执行自己自定义的逻辑

2.7 执行Runner, 启动就绪

执行Runner前, 使用应用上下文发布ApplicationStartedEvent事件 listeners.started(context);

    private void callRunners(ApplicationContext context, ApplicationArguments args) {
        List<Object> runners = new ArrayList<>();
        // 获取类型为ApplicationRunner和CommandLineRunner所有的Runner
        runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
        runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
        AnnotationAwareOrderComparator.sort(runners);
        // 遍历执行Runner的run方法
        for (Object runner : new LinkedHashSet<>(runners)) {
            if (runner instanceof ApplicationRunner) {
                callRunner((ApplicationRunner) runner, args);
            }
            if (runner instanceof CommandLineRunner) {
                callRunner((CommandLineRunner) runner, args);
            }
        }
    }

    private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
        try {
            (runner).run(args);
        }
        catch (Exception ex) {
            throw new IllegalStateException("Failed to execute ApplicationRunner", ex);
        }
    }

说明:

  1. 默认情况下, SpringBoot项目是没有添加ApplicationRunner和CommandLineRunner的bean的, 故runners列表为空, 不会执行任何操作
  2. Runner目前只是提供给我们做扩展, 我们可以自定义一个Runner, 添加@Component注解, 待Spring启动完成时执行我们的Runner完成我们的自定义逻辑

执行Runner后, 使用应用上下文发布ApplicationReadyEvent事件 listeners.running(context);

三. 拓展

3.1 Environment添加PropertySource过程

继承体系和实现如下:
在这里插入图片描述
内部属性如下:
在这里插入图片描述

这里分析SpringBoot启动中StandardServletEnvironment添加propertySources的过程.

3.1.1 执行父类AbstractEnvironment的构造器方法

   	private final MutablePropertySources propertySources = new MutablePropertySources();
	public AbstractEnvironment() {
		customizePropertySources(this.propertySources);
	}

此时: propertySources.propertySourceList为空列表
在这里插入图片描述

3.1.2 执行StandardServletEnvironment的customizePropertySources方法

添加了servletConfigInitParams和servletContextInitParams两个propertySource. 空对象里面没有属性值

	protected void customizePropertySources(MutablePropertySources propertySources) {
		propertySources.addLast(new StubPropertySource("servletConfigInitParams"));
		propertySources.addLast(new StubPropertySource("servletContextInitParams"));
		if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
			propertySources.addLast(new JndiPropertySource("jndiProperties"));
		}
		super.customizePropertySources(propertySources);
	}

在这里插入图片描述

3.1.3 执行父类StandardEnvironment的customizePropertySources方法

添加了systemProperties和systemEnvironment两个propertySource.

	protected void customizePropertySources(MutablePropertySources propertySources) {
		// 获取项目运行属性. 如: java.vm.info -> mixed mode
		propertySources.addLast(new PropertiesPropertySource("systemProperties", getSystemProperties()));
		// 获取计算机环境变量. 如: JAVA_HOME -> F:\jdk
		propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment", getSystemEnvironment()));
	}

在这里插入图片描述

3.1.4 执行ConfigurationPropertySources#attach方法

添加了configurationProperties这个propertySource.

	public static void attach(Environment environment) {
		Assert.isInstanceOf(ConfigurableEnvironment.class, environment);
		MutablePropertySources sources = ((ConfigurableEnvironment) environment).getPropertySources();
		PropertySource<?> attached = sources.get("configurationProperties");
		if (attached != null && attached.getSource() != sources) {
			sources.remove("configurationProperties");
			attached = null;
		}
		if (attached == null) {
			sources.addFirst(new ConfigurationPropertySourcesPropertySource("configurationProperties",
					new SpringConfigurationPropertySources(sources)));
		}
	}

在这里插入图片描述

3.1.5 SpringCloud中存在父子容器创建过程, 父容器创建完成后, 会给子容器Environment添加一个propertySource

在这里插入图片描述

3.1.6 ConfigFileApplicationListener执行EnvironmentPostProcessor加载其余的配置文件

环境准备好后, 监听ApplicationEnvironmentPreparedEvent事件, 其中ConfigFileApplicationListener也会监听该事件进行处理
ConfigFileApplicationListener执行流程如下(感兴趣的可以去看源码, 源码不复杂):

  • 遍历EnvironmentPostProcessor(ConfigFileApplicationListener也是环境后置处理器, 也加到列表遍历执行). 处理器实现类在spring.factories中
  • 执行postProcessEnvironment方法 (以下为ConfigFileApplicationListener的后置处理逻辑, 其他处理器请看源码)
  • 添加一个名为random的propertySource到Environment
  • 添加一个null的profile, 添加spring.profiles.active和spring.profiles.include下的值, 遍历profile列表
  • 获取文件文件夹地址和文件名(不含后缀)
    • ConfigFileApplicationListener.Loader#getSearchLocations()获取指定的配置文件路径, 没有指定则返回默认路径classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/
    • ConfigFileApplicationListener.Loader#getSearchNames获取文件名, 如bootstrap, application
  • 遍历加载器PropertySourceLoader, 拼接出文件完整路径, 判断文件资源是否存在, 存在则加载解析文件. PropertySourceLoader常见实现类如下
    • YamlPropertySourceLoader 加载yaml和yml结尾的配置文件
    • PropertiesPropertySourceLoader 加载properties和xml结尾的配置文件
  • 使用ConfigFileApplicationListener.Loader#loaded属性暂存各个profile下的读取的配置文件属性信息
  • 添加loaded属性的所有PropertySource到Environment中 (ConfigFileApplicationListener.Loader#addLoadedPropertySource中完成添加)
    • 添加的 propertySource都是有顺序的, 有profile的必定在没有的前面, 例如application-dev.yml必定在application.yml前

3.2 SpringCloud的父子容器

见系列文章-SpringCloud父子容器源码浅析

3.3 应用上下文

        Spring容器最基本的接口就是BeanFactory. BeanFactory负责配置、创建、管理Bean.ApplicationContext由BeanFactory派生而来
        应用上下文也经常被叫做容器
        常见的实现类有:

  • ClassPathXmlApplicationContext:可以加载类路径下的配置文件(要求配置文件必须在类路径之下)
  • FileSystemXmlApplicationContext:可以加载磁盘中任意路径下的配置文件(要求具有访问权限)
  • AnnotationConfigApplicationContext:用于读取注解创建容器
  • AnnotationConfigServletWebServerApplicationContext:SpringBoot的servlet项目使用的容器实现
    主要的继承关系图如下:
    在这里插入图片描述

3.4 BeanFactoryPostProcessor与BeanPostProcessor的区别

  • BeanFactoryPostProcessor: bean工厂的后置处理器, 针对BeanFactory的扩展,修改bean的定义属性(bean定义之后, 实例化bean之前)
  • BeanPostProcessor: bean的后置处理器, 针对Bean的扩展,对bean进行处理(实例化bean之后, 初始化bean前后调用)
    区别对比如下如: 图片来源: Spring面试系列—BeanFactoryPostProcessor和BeanPostProcessor的区别
    在这里插入图片描述

四. 思考

  • ConfigurationPropertySources.attach(environment)为什么执行两次? 第一次是否多余? 添加的configurationProperties属性源的作用是什么?
  • SpringCloud父子容器的作用? 为什么这样设计?
  • SpringApplication#afterRefresh是空实现, 它的作用是什么? 为什么这样设计?

五. 参考文档

springboot启动过程源码分析: https://blog.csdn.net/wufaqidong1/article/details/126236638
springboot启动流程源码解析: https://blog.csdn.net/promsing/article/details/126469944

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值