上篇文章说SpringApplication构造方法都做了些什么,下面继续说new SpringApplication().run方法
跟源码流程图:
看一下ConfigurableApplicationContext run的代码:
public ConfigurableApplicationContext run(String... args) {
// 创建计时器
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
// 设置属性
this.configureHeadlessProperty();
// spring中监听器的使用,这些对象想创建,就得知道监听器的全路径
// 会从spring.factory中读取
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
Collection exceptionReporters;
try {
// 初始化默认应用参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 根据监听器和默认的参数 来准备spring所需要的环境
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
this.configureIgnoreBeanInfo(environment);
// 打印出banner
Banner printedBanner = this.printBanner(environment);
// 创建应用上下文
context = this.createApplicationContext();
// 异常报告
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
// 准备应用上下文
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 刷新上下文
this.refreshContext(context);
// 刷新
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
// 执行callRunners, 支持自定义run方法
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
然后看一下==this.refreshContext(context)==这个方法的作用:
完善了流程图
主要方法为refresh():
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
// context设置 启动日期/当前状态/初始环境/验证
this.prepareRefresh();
// 创建一个bean工程,
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
// 注册scope
this.postProcessBeanFactory(beanFactory);
// 调用所有bean工厂,对bean进行处理
this.invokeBeanFactoryPostProcessors(beanFactory);
// 拦截bean,
this.registerBeanPostProcessors(beanFactory);
// 国际化操作
this.initMessageSource();
// 广播事件
this.initApplicationEventMulticaster();
// 特殊bean 比如tomcat
this.onRefresh();
// 注册监听器
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
然后继续跟进,流程图为:
public WebServer getWebServer(ServletContextInitializer... initializers) {
if (this.disableMBeanRegistry) {
Registry.disableRegistry();
}
Tomcat tomcat = new Tomcat();
File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
connector.setThrowOnFailure(true);
tomcat.getService().addConnector(connector);
this.customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
this.configureEngine(tomcat.getEngine());
Iterator var5 = this.additionalTomcatConnectors.iterator();
while(var5.hasNext()) {
Connector additionalConnector = (Connector)var5.next();
tomcat.getService().addConnector(additionalConnector);
}
this.prepareContext(tomcat.getHost(), initializers);
return this.getTomcatWebServer(tomcat);
}