承接前文springboot情操陶冶-SpringApplication(一),本文将对run()方法作下详细的解析
SpringApplication#run()
main函数经常调用的run()方法是我们分析的关键,先上源码
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>(); // 读取java.awt.headless系统变量,默认为true.常用于linux图片的渲染 configureHeadlessProperty(); // 获取SpringApplicationRunListener接口集合并实例化调用公共接口starting() SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(); try { ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); // environment configuration ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); // spring.beaninfo.ignore属性读取 configureIgnoreBeanInfo(environment); // springboot的banner样图 Banner printedBanner = printBanner(environment); // 创建spring应用上下文(尚未刷新) context = createApplicationContext(); // SpringBootExceptionReporter接口集合读取 exceptionReporters = getSpringFactoriesInstances( SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context); // applicationContext configuration prepareContext(context, environment, listeners, applicationArguments, printedBanner); // 刷新spring应用上下文 refreshContext(context); afterRefresh(context, applicationArguments); stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } // SpringApplicationRunListener接口的started()方法调用 listeners.started(context); callRunners(context, applicationArguments); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, listeners); throw new IllegalStateException(ex); } try { // SpringApplicationRunListener接口的running()方法调用 listeners.running(context); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, null); throw new IllegalStateException(ex); } return context; }以上的代码注释有点多,笔者分块来进行罗列分析
SpringApplication#getRunListeners()
获取SpringApplicationRunListener接口集合并实例化,根据前文得知,读取的是META\spring.factories文件中的对应属性,
此处笔者以org.springframework.boot.context.event.EventPublishingRunListener为例。
先观察下其构造函数
public EventPublishingRunListener(SpringApplication application, String[] args) { this.application = application; this.args = args; this.initialMulticaster = new SimpleApplicationEventMulticaster(); for (ApplicationListener<?> listener : application.getListeners()) { this.initialMulticaster.addApplicationListener(listener); } }注意application.getListeners()方法,根据前文得知,其会拿到类型为ApplicationListener的集合并存入至SimpleApplicationEventMulticaster广播类中;
其余方法,比如starting()/started()/environmentPrepared()等等方法均是由其统一调用所有的ApplicationListener接口的对应事件。笔者此处以starting()为例
@Override public void starting() { this.initialMulticaster.multicastEvent( new ApplicationStartingEvent(this.application, this.args)); }其会找寻支持响应ApplicationStartingEvent事件的Listeners,并执行相应的事件方法。响应的监听器有LoggingApplicationListener和LiquibaseServiceLocatorApplicationListener等
SpringApplication#prepareEnvironment()
