1. initialize 方法
SpringApplication
的构造函数只调用了 initialize
方法:
private void initialize(Object[] sources) {if (sources != null && sources.length > 0) {// 把应用指定的配置类加入配置扫描的启动来源this.sources.addAll(Arrays.asList(sources));}// 判断应用是否是 web 应用,主要用于决定采用哪种具体的上下文实现this.webEnvironment = deduceWebEnvironment();// 利用定制的 SPI 实现 SpringFactoriesLoader 加载 ApplicationContextInitializer 的所有实现并设置到 initializers 属性setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));// 利用定制的 SPI 实现 SpringFactoriesLoader 加载 ApplicationListener 的所有实现并设置到 listeners 属性setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 找出启动类:线程栈上 main 方法所处的类this.mainApplicationClass = deduceMainApplicationClass();}
该方法的逻辑主要如下:
把启动类加入 sources 属性。
判断是否是 web 应用并设置到 webEnvironment 属性。
加载所有的 ApplicationContextInitializer 并设置到 initializers 属性。
加载所有的 ApplicationListener 并设置到 listeners 属性。
找出 main 类设置到 mainApplicationClass。
2. run 方法
public ConfigurableApplicationContext run(String... args) {// StopWatch 主要用来统计应用的启动时间StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;FailureAnalyzers analyzers = null;// 配置 AWT 的 headless 属性configureHeadlessProperty();// 初始化事件广播器,用于广播事件SpringApplicationRunListeners listeners = getRunListeners(args);// 触发 SpringApplicationRunListener.starting 方法// 向 ApplicationListener 广播 ApplicationStartedEvent 事件listeners.starting();try {// 封装命令行参数,后面会注册到上下文里ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);// 创建并准备 EnvironmentConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);// 打印 BannerBanner printedBanner = printBanner(environment);// 创建 ApplicationContextcontext = createApplicationContext();// 创建失败分析器analyzers = new FailureAnalyzers(context);//prepareContext(context, environment, listeners, applicationArguments, printedBanner);// 刷新上下文,加载所有的Bean定义并实例化非延迟加载的单例BeanrefreshContext(context);// 获取所有的 ApplicationRunner 和 CommandLineRunner 并执行其回调afterRefresh(context, applicationArguments);// 广播 ApplicationReadyEvent或ApplicationFailedEvent事件listeners.finished(context, null);// 终止计时stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}return context;} catch (Throwable ex) {handleRunFailure(context, listeners, analyzers, ex);throw new IllegalStateException(ex);}}
run 方法的核心逻辑:
创建 StopWatch 用于记录启动耗时;
创建并准备 Enviroment。加载所有的配置文件和处理 Profile 。
创建并准备 ApplicationContext ,把
ConfigurationClassPostProcessor
注册到上下文底层的BeanFacotry
。刷新 ApplicationContext。
获取所有的
ApplicationRunner
和CommandLineRunner
并执行其回调。广播 ApplicationReadyEvent或ApplicationFailedEvent事件。
这个流程非常简单,不涉及具体的配置文件解析、加载,bean 定义扫描、解析、加载、实例化 bean 等。就是 SpringBoot 特有的流程,比如打印 Banner、回调 Runner 方法,中间适时广播事件。
欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。

文章转载自coderbee笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




