Spring Boot是利用 SpringApplication类的static的 run 方法进行启动的,调用的图:
//调用示例:
public static void main(String[] args) throws Exception {
SpringApplication.run(Examples.class, args);
}
SpringApplication类提供了两个static的run方法:
public static ConfigurableApplicationContext run(Object source, String... args) {
return run(new Object[] { source }, args);
}
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
return new SpringApplication(sources).run(args);
}
上面两个方法其实就是一个,最终都会创建一个SringApplication实例,在构造时会处理传入的 sources 参数,SpringApplication构造方法如下:
public SpringApplication(Object... sources) {
initialize(sources);
}
private void initialize(Object[] sources) {
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}
this.webEnvironment = deduceWebEnvironment(); //根据当前项目是否包含相应的类,来推断当前项目是否是web项目
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass();
}
getSpringFactoriesInstances 方法是用来查找每个jar和类路径下的/META-INF/spring.factories文件,并获取其中的特定接口的配置的,例如在spring-boot-autoconfigure-1.5.2.RELEASE.jar中的spring.factories文件,其中对
ApplicationContextInitializer接口和 ApplicationListener接口的配置如下:
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
上面的代码完成初始化之后,紧接着就是调用SpringApplication类的实例 run方法,代码如下:
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
analyzers = new FailureAnalyzers(context);
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
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);
}
}
SpringApplication类的实例 run方法做了如下这些事:
1.创建了一个 ApplicationContext 实例,在 createApplicationContext()方法中完成了实例的创建
webEnvironment属性为true,则创建org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext 类的实例,否则创建 org.springframework.context.annotation.AnnotationConfigApplicationContext的实例
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);
}
2.产生一个CommandLinePropertySource用来把命令行的参数转化为spring容器启动需要的一些属性配置
3. 启动 ApplicationContext 容器加载Bean
3.待定(Trigger any CommandLineRunner beans)
4.一般在启动类上要加@EnableAutoConfiguration这个注解,用来获取各种配置信息,
(1)这个注解所加的启动类的包将作为Spring容器扫描Bean的basePackage属性
5.项目中的一些Bean的配置可以是xml方式,但Spring Boot建议使用@Configuration注解
总结一下:
SpringApplication类的static的 run 方法做的事就是先实例化一个 SpringApplication实例,然后调用其 initialize 方法进行一些初始化工作,接着就调用SpringApplication实例的run方法启动容器。