刷新 IOC 容器 refreshContext
private void refreshContext(ConfigurableApplicationContext context) {if (this.registerShutdownHook) {
try {context.registerShutdownHook();
}
catch (AccessControlException ex) {// Not allowed in some environments.}
}
//spring 的外围源码
refresh((ApplicationContext) context);
}
============== 进入 refresh((ApplicationContext) context);
@Deprecated
protected void refresh(ApplicationContext applicationContext) {Assert.isInstanceOf(ConfigurableApplicationContext.class, applicationContext);
refresh((ConfigurableApplicationContext) applicationContext);
}
protected void refresh(ConfigurableApplicationContext applicationContext) {applicationContext.refresh();
}
@Override
public final void refresh() throws BeansException, IllegalStateException {
try {super.refresh();
}
catch (RuntimeException ex) {
WebServer webServer = this.webServer;
if (webServer != null) {webServer.stop();
}
throw ex;
}
}
//spring ioc 容器的经典的初始化过程
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {this.postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
// 实例化容器中所有的组件
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();} catch (BeansException var10) {if (this.logger.isWarnEnabled()) {this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt:" + var10);
}
this.destroyBeans();
this.cancelRefresh(var10);
throw var10;
} finally {this.resetCommonCaches();
contextRefresh.end();}
}
}
callRunners(context, applicationArguments)
private void callRunners(ApplicationContext context, ApplicationArguments args) {
// 筹备 runners 汇合
List<Object> runners = new ArrayList<>();
//getBeansOfType:依据类型获取组件 CommandLineRunner,ApplicationRunner
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
// 合并所有 runner 并且依照 @Order 进行排序
AnnotationAwareOrderComparator.sort(runners);
// 遍历遍历所有的 runner。调用各自的 run 办法
for (Object runner : new LinkedHashSet<>(runners)) {if (runner instanceof ApplicationRunner) {callRunner((ApplicationRunner) runner, args);
}
if (runner instanceof CommandLineRunner) {callRunner((CommandLineRunner) runner, args);
}
}
}
@FunctionalInterface
public interface ApplicationRunner {
/**
* Callback used to run the bean.
* @param args incoming application arguments
* @throws Exception on error
*/
void run(ApplicationArguments args) throws Exception;
}
@FunctionalInterface
public interface CommandLineRunner {
/**
* Callback used to run the bean.
* @param args incoming main method arguments
* @throws Exception on error
*/
void run(String... args) throws Exception;
}
handleRunFailure(context, ex, listeners);
private void handleRunFailure(ConfigurableApplicationContext context, Throwable exception,
SpringApplicationRunListeners listeners) {
try {
try {handleExitCode(context, exception);
if (listeners != null) {// 调用 listeners.failed(context, exception);
listeners.failed(context, exception);
}
}
finally {reportFailure(getExceptionReporters(context), exception);
if (context != null) {context.close();
}
}
}
catch (Exception ex) {logger.warn("Unable to close ApplicationContext", ex);
}
ReflectionUtils.rethrowRuntimeException(exception);
}
// 如果有异样,持续捕捉异样
handleRunFailure(context, ex, null);
private void handleRunFailure(ConfigurableApplicationContext context, Throwable exception,
SpringApplicationRunListeners listeners) {
try {
try {handleExitCode(context, exception);
if (listeners != null) {
//running 如果有问题。持续告诉 failed。// 调用所有 Listener 的 failed;告诉所有的监听器 failed 以后我的项目运行失败
listeners.failed(context, exception);
}
}
finally {reportFailure(getExceptionReporters(context), exception);
if (context != null) {context.close();
}
}
}
catch (Exception ex) {logger.warn("Unable to close ApplicationContext", ex);
}
ReflectionUtils.rethrowRuntimeException(exception);
}