断点源码
只分析主要方法
源码版本:1.5.10
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@SpringBootApplication包含以下三个注解
// 使用JavaConfig形式,不用xml
@SpringBootConfiguration
// 开启自动配置
@EnableAutoConfiguration
// 自动包扫描
@ComponentScan
1. initialize方法
private void initialize(Object[] sources) {
// 1.初始化成员变量sources
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}
// 2.初始化成员变量webEnvironment,判断应用类型
// javax.servlet.Servlet 或者 org.springframework.web.context.ConfigurableWebApplicationContext
this.webEnvironment = deduceWebEnvironment();
// 3.初始化成员变量initializers
// spring.factories文件中key为ApplicationContextInitializer的类实例化
// 设置到SpringApplication的initializers属性中,找出所有的应用程序初始化器
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
// 4.初始化成员变量listeners
// spring.factories文件中key为ApplicationListener的类实例化
// 设置到SpringApplication的listeners属性中,找出所有的应用程序事件监听器
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 5.初始化成员变量mainApplicationClass,找应用的入口类
this.mainApplicationClass = deduceMainApplicationClass();
}
2. run方法
public ConfigurableApplicationContext run(String... args) {
// 1.开始记录时间
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
// 2.设置java.awt.headless系统属性为true
configureHeadlessProperty();
// 3.获取SpringApplicationRunListeners,内部只有一个EventPublishingRunListener
SpringApplicationRunListeners listeners = getRunListeners(args);
// 4.接受ApplicationStartedEvent事件的listener会执行相应的操作
listeners.starting();
try {
// 5.构造一个应用程序参数持有类
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
// 6.根据SpringApplicationRunListeners以及参数来准备环境
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
// 7.打印logo
Banner printedBanner = printBanner(environment);
// 8.创建Spring容器
context = createApplicationContext();
// 9.创建异常分析器
analyzers = new FailureAnalyzers(context);
// 10.Spring上下文前置处理
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
// 11.Spring上下文刷新
refreshContext(context);
// 12.容器创建完成之后执行额外一些操作
afterRefresh(context, applicationArguments);
// 13.广播出ApplicationReadyEvent事件给相应的监听器执行
listeners.finished(context, null);
// 14.停止计时
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);
}
}
3. run方法中的prepareContext方法
private void prepareContext(ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
// 1.把环境和上下文关联起来
context.setEnvironment(environment);
// 2.为上下文配置Bean生成器以及资源加载器
postProcessApplicationContext(context);
// 3.调用初始化器
applyInitializers(context);
// 4.触发Spring Boot启动过程的contextPrepared事件
listeners.contextPrepared(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
// 5.添加两个Spring Boot中的特殊单例Bean:springApplicationArguments和springBootBanner
context.getBeanFactory().registerSingleton("springApplicationArguments",
applicationArguments);
if (printedBanner != null) {
context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
}
// Load the sources
// 6.加载sources:对于DemoApplication而言,这里的sources集合只包含了它一个class对象
Set<Object> sources = getSources();
Assert.notEmpty(sources, "Sources must not be empty");
// 7.加载动作:构造BeanDefinitionLoader并完成Bean定义的加载
load(context, sources.toArray(new Object[sources.size()]));
// 8.触发Spring Boot启动过程的contextLoaded事件
listeners.contextLoaded(context);
}