在初始化的initialize方法完成后,就进入SpringApplication的run方法了,run()方法如下:
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; FailureAnalyzers analyzers = null; configureHeadlessProperty(); SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(); try { ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); Banner printedBanner = printBanner(environment); context = createApplicationContext(); analyzers = new FailureAnalyzers(context); prepareContext(context, environment, listeners, applicationArguments, printedBanner); refreshContext(context); afterRefresh(context, applicationArguments); listeners.finished(context, null); 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); } }
一、StopWatch
在stopWatch中,分别启用了它的start与stop方法,用来统计了程序启动的时间。
二、configureHeadlessProperty();
在run方法的此方法中,如果不指定的话,就设置java.awt.headless属性为true。
三、SpringApplicationRunListeners listeners = getRunListeners(args);
其方法内容如下:
private SpringApplicationRunListeners getRunListeners(String[] args) { Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class }; return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances( SpringApplicationRunListener.class, types, this, args)); }
这个方法与上篇博文中的获取Linstener实例的方式一样,获取了spring.factories中,key为“org.springframework.boot.SpringApplicationRunListener”的所有类型,并将返回的所有实例,以及以SpringApplication为参数的logger生成了对象:
private final Log log; private final List<SpringApplicationRunListener> listeners; SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) { this.log = log; this.listeners = new ArrayList<SpringApplicationRunListener>(listeners); }
四、listeners.starting();
在此方法中,使用了上文取到的listeners,其实只有一个listener,就是EventPublishingRunListener,后面的调用方式与spring中调用ApplicationListener和ApplicationEvent的方式一样,不多做介绍。
五、ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);
关于这篇我们单独写了一篇文章进行介绍,
内容点击这里。
六、Banner printedBanner = printBanner(environment);
此方法是打印了springboot的Banner图片,没有业务作用。
七、context = createApplicationContext();
此方法是初始化了一个ConfigurableApplicationContext类型的实例,在web环境中,创建的实例类型为:
public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework." + "boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext";
八、analyzers = new FailureAnalyzers(context);
这个方法,创建了FailureAnalyzers类型的实例,
我们在此文章中专门介绍。
九、prepareContext(context, environment, listeners, applicationArguments,printedBanner);
关于此段的介绍,
在此篇博文中。
十、refreshContext(context);
这个方法其实是调用了AbstractApplicationContext的refresh()方法,但是有一点尤其注意,这也是springboot项目的重中之重,就是tomcat容器的启动也是在这里操作的,refresh()方法中的onfresh()方法被EmbeddedApplicationContext重写了,在此做了tomcat的启动加载,如下:
@Override protected void onRefresh() { super.onRefresh(); try { createEmbeddedServletContainer(); } catch (Throwable ex) { throw new ApplicationContextException("Unable to start embedded container", ex); } }关于tomcat的加载是非常大的一块我们在介绍完run方法后, 会单独介绍这块内容。