SpringApplication 的初始化过程分析 : initialize()

本文详细解析了SpringBoot启动过程中的关键步骤,包括初始化过程、判断Web应用环境、设置ApplicationContextInitializer和ApplicationListener等内容。

基于 Springboot 1.5.8 源代码分析

SpringApplication 的初始化过程由方法 initialize() 完成

1.接收和设置源 sources

sources 是用于识别bean定义的信息来源, 参数类型是一个对象数组,实际上对于 Spring boot 应用来讲, 缺省情况下,这里只传入了应用入口程序的类作为参数。下面是 sources 被传入 initialize() 方法的过程。

// 应用入口程序类
@SpringBootApplication
public class Application {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

上面main方法中将应用程序入口类作为下面run方法的参数source,而下面方法将source变成数组形式 :

public static ConfigurableApplicationContext run(Object source, String... args) {
	return run(new Object[] { source }, args);
}

// 进一步的实现,变成数组形式的 sources 被作为 SpringApplication 类构造函数的参数传入
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
	return new SpringApplication(sources).run(args);
}

SpringApplication 类将数组形式的 sources 传递给自己的初始化方法 initialize()

public SpringApplication(Object... sources) {
	initialize(sources);
}
2. 推断是否Web应用环境

如果这些类在 classpath 上都存在,则认为这是个Web应用环境 :

  1. javax.servlet.Servlet
  2. org.springframework.web.context.ConfigurableWebApplicationContext
3. 设置 ApplicationContextInitializer

使用内部工具类SpringFactoriesLoader加载所有ApplicationContextInitializer实现类并实例化 :

//缺省 Web SpringApplication 应用会有以下 6 个 ApplicationContextInitializer: 
//1.初始化任务委托给Environment指定的初始化器,
//相当于给外界提供了一个添加自定义ApplicationContextInitializer的入口
//委托给Environment属性context.initializer.classes下指定的ApplicationContextInitializer类,
DelegatingApplicationContextInitializer

//2.设置Spring ApplicationContext ID
//这些环境变量会被用来产生Spring ApplicationContext ID : 
// spring.application.name,vcap.application.name,spring.config.name
// 如果没有找到以上属性设置,ID使用 application
ContextIdApplicationContextInitializer

//3.用于报告一般配置错误,
//添加BeanFactoryPostProcessor : ConfigurationWarningsPostProcessor
ConfigurationWarningsApplicationContextInitializer 

//4.添加 ApplicationListener<EmbeddedServletContainerInitializedEvent>
ServerPortInfoApplicationContextInitializer

//5.在ConfigurationClassPostProcessor和Spring boot之间增加一个共享的CachingMetadataReaderFactory
//添加BeanFactoryPostProcessor : CachingMetadataReaderFactoryPostProcessor
SharedMetadataReaderFactoryContextInitializer

//6.将ConditionEvaluationReport写到log,在DEBUG级别下输出
//添加AutoConfigurationReportListener
AutoConfigurationReportLoggingInitializer
4. 设置 ApplicationListener

使用内部工具类 SpringFactoriesLoader 加载所有类型 ApplicationListener 并实例化。

// 缺省 Web SpringApplication 应用会有以下10个 ApplicationListener
ConfigFileApplicationListener
AnsiOutputApplicationListener
LoggingApplicationListener
ClasspathLoggingApplicationListener
BackgroundPreinitializer
DelegatingApplicationListener
ParentContextCloserApplicationListener
ClearCachesApplicationListener
FileEncodingApplicationListener
LiquibaseServiceLocatorApplicationListener
5. 推断应用程序主类

实例化一个运行时异常,从其堆栈跟踪信息中找到 main() 方法所在的类。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值