import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication // <1>
public class MVCApplication {
public static void main(String[] args) {
SpringApplication.run(MVCApplication.class, args); // <2>
}
}
public static void main(String[] args) throws Exception {
SpringApplication.run(new Class<?>[0], args);
}
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
public SpringApplication(Class<?>... primarySources) {
this(null, primarySources);
}
/**
* 资源加载器
*/
private ResourceLoader resourceLoader;
/**
* 主要的 Java Config 类的数组
*/
private Set<Class<?>> primarySources;
/**
* Web 应用类型
*/
private WebApplicationType webApplicationType;
/**
* ApplicationContextInitializer 数组
*/
private List<ApplicationContextInitializer<?>> initializers;
/**
* ApplicationListener 数组
*/
private List<ApplicationListener<?>> listeners;
@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
run方法
public ConfigurableApplicationContext run(String... args) {
// <1> 创建 StopWatch 对象,并启动。StopWatch 主要用于简单统计 run 启动过程的时长。
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
// <2> 配置 headless 属性
configureHeadlessProperty();
// 获得 SpringApplicationRunListener 的数组,并启动监听
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
// <3> 创建 ApplicationArguments 对象
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// <4> 加载属性配置。执行完成后,所有的 environment 的属性都会加载进来,包括 application.properties 和外部的属性配置
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
// <5> 打印 Spring Banner
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
// <7> 异常报告器
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
// <8> 主要是调用所有初始化类的 initialize 方法
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// <9> 初始化 Spring 容器。
refreshContext(context);
// <10> 执行 Spring 容器的初始化的后置逻辑。默认实现为空。
afterRefresh(context, applicationArguments);
// <11> 停止 StopWatch 统计时长
stopWatch.stop();
// <12> 打印 Spring Boot 启动的时长日志。
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
// <13> 通知 SpringApplicationRunListener 的数组,Spring 容器启动完成。
listeners.started(context);
// <14> 调用 ApplicationRunner 或者 CommandLineRunner 的运行方法。
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
// <14.1> 如果发生异常,则进行处理,并抛出 IllegalStateException 异常
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
// <15> 通知 SpringApplicationRunListener 的数组,Spring 容器运行中。
try {
listeners.running(context);
}
catch (Throwable ex) {
// <15.1> 如果发生异常,则进行处理,并抛出 IllegalStateException 异常
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments) {
// Create and configure the environment
// <1> 创建 ConfigurableEnvironment 对象,并进行配置
ConfigurableEnvironment environment = getOrCreateEnvironment();
configureEnvironment(environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach(environment);
// <2> 通知 SpringApplicationRunListener 的数组,环境变量已经准备完成。
listeners.environmentPrepared(environment);
// <3> 绑定 environment 到 SpringApplication 上
bindToSpringApplication(environment);
// <4> 如果非自定义 environment ,则根据条件转换
if (!this.isCustomEnvironment) {
environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
deduceEnvironmentClass());
}
// <5> 如果有 attach 到 environment 上的 MutablePropertySources ,则添加到 environment 的 PropertySource 中。
ConfigurationPropertySources.attach(environment);
return environment;
}