SpringBoot 启动过程
基于 Spring 的事件发布和监听机制开始说起。
初始化
启动流程主要分为三个部分,第一部分进行 SpringApplication
的初始化模块,配置一些基本的环境变量、资源、构造器、监听器。
自动配置
@EnableAutoConfiguration
完成了一下功能:
从 classpath
中搜寻所有的 META-INF/spring.factories
配置文件,并将其中 org.springframework.boot.autoconfigure.EnableutoConfiguration
对应的配置项通过反射实例化为对应的标注了 @Configuration
的 JavaConfig
形式的 IoC 容器配置类,然后汇总为一个并加载到 IoC 容器。
加载 ApplicationContextInitializer
加载所有配置的 ApplicationContextInitializer
并进行实例化,加载 ApplicationContextInitializer
是在 SpringFactoriesLoader.loadFactoryNames
方法里面进行的。这个方法会尝试从类路径的 META-INF/spring.factories
读取相应配置文件,然后进行遍历,读取配置文件中Key为:org.springframework.context.ApplicationContextInitializer
的 value。以 spring-boot 这个包为例,它的 META-INF/spring.factories
部分定义如下所示:
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer
接口
ApplicationContextInitializer
的定义
public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {
/**
* Initialize the given application context.
* @param applicationContext the application to configure
*/
void initialize(C applicationContext);
}
加载 ApplicationListener
以 spring-boot 这个包中的 spring.factories
为例,看看相应的 Key-Value :
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener,\
org.springframework.boot.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.logging.LoggingApplicationListener
接口
ApplicationListener
的定义
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
开始启动
第二部分实现了应用具体的启动方案,包括启动流程的监听模块、加载配置环境模块、及核心的创建上下文环境模块。
加载 SpringApplicationRunListener
从 META-INF/spring.factories
中读取 Key 为 org.springframework.boot.SpringApplicationRunListener 的Values
:
比如在 spring-boot 包中的定义的 spring.factories
:
# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener
准备 Environment
protected void configureEnvironment(ConfigurableEnvironment environment,
String[] args) {
configurePropertySources(environment, args);
configureProfiles(environment, args);
}
创建 Context
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
contextClass = Class.forName(this.webEnvironment
? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS);
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, "
+ "please specify an ApplicationContextClass",
ex);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);
}
// WEB应用的上下文类型
public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext";
// 非WEB应用的上下文类型
public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."
+ "annotation.AnnotationConfigApplicationContext";