run()方法(运行程序)
public ConfigurableApplicationContext run(String... args) {
//开始和停止的监听
StopWatch stopWatch = new StopWatch();
stopWatch.start();
//声明一个IOC容器,暂时为空,后面创建
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
//与awt应用相关的
configureHeadlessProperty();
//获取SpringApplicationRunListeners
//详见注释1
SpringApplicationRunListeners listeners = getRunListeners(args);
//回调所有的获取SpringApplicationRunListener.starting()方法
listeners.starting();
try {
//封装命令行参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//准备环境
//详见注释2
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
//打印控制台springboot图标
Banner printedBanner = printBanner(environment);
//创建ApplicationContext,IOC容器
//详见注释3
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//准备所有
//详见注释4
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//刷新容器;IOC容器初始化(如果是web应用还会创建嵌入式的Tomcat)
//扫描,创建,加载所有组件的地方;(配置类,组件,自动配置)
refreshContext(context);
//从IOC容器中获取所有的ApplicationRunner和CommandLineRunner
//详见注释5
afterRefresh(context, applicationArguments);
//所有的SpringApplicationRunListener回调finished方法
listeners.finished(context, null);
return context;
}
注释
1.getRunListeners():
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
通过getSpringFactoriesInstances获取,也是从类路径下META‐INF/spring.factories找
2.prepareEnvironment():
//获取或创建环境
ConfigurableEnvironment environment = getOrCreateEnvironment();
//配置环境
configureEnvironment(environment, applicationArguments.getSourceArgs())
//创建环境完成后回调SpringApplicationRunListener.environmentPrepared();表示环境准备完成
listeners.environmentPrepared(environment);
3.createApplicationContext():
//判断当前应用环境来创建对应的IOC容器
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
}
4.prepareContext():
//将environment保存到IOC中
context.setEnvironment(environment);
//IOC容器后置处理(注册一些组件)
postProcessApplicationContext(context);
//回调之前创建SpringApplication对象时保存的所有的ApplicationContextInitializer的initialize()方法
applyInitializers(context);
//applyInitializers代码片段:
for (ApplicationContextInitializer initializer : getInitializers()) {
Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
ApplicationContextInitializer.class);
Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
initializer.initialize(context);
//回调之前创建SpringApplication对象时保存的所有的listeners的contextPrepared()方法
listeners.contextPrepared(context);
//contextPrepared代码片段:
for (SpringApplicationRunListener listener : this.listeners) {
listener.contextPrepared(context);
//日志记录
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
//注册命令行参数对象
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
//注册打印的图标
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
//获取主配置类
Set<Object> sources = getAllSources();
//prepareContext运行完成以后回调所有的listeners的contextLoaded();
listeners.contextLoaded(context);
5.afterRefresh()里的callRunners():
//从IOC容器中获取所有的ApplicationRunner和CommandLineRunner
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
//ApplicationRunner优先级大于CommandLineRunner
for (Object runner : new LinkedHashSet<>(runners)) {
if (runner instanceof ApplicationRunner) {
callRunner((ApplicationRunner) runner, args);
}
if (runner instanceof CommandLineRunner) {
callRunner((CommandLineRunner) runner, args);
}
}
不同版本spring boot源码略有差距