springboot源码解析(二)SpringApplication的run方法

在初始化的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方法后, 会单独介绍这块内容

猜你喜欢

转载自blog.csdn.net/lz710117239/article/details/80096698