在使用Spring Boot的时候,都知道通过SpringApplication.run(MyApplicaton)
即可创建一个Spring应用,但是大家有没有注意这个方法的返回值呢?
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class<?>[] { primarySource }, args);
}
run()
方法返回了一个ConfigurableApplicationContext
的实例,那么这个实例是如何被创建的呢,创建的又是哪个对象的实例呢?
本文将通过源码的方式,来解决以下问题:
ConfigurableApplicationContext
的对象实例的?ConfigurableApplicationContext
的对象实例是哪个对象的?对象指是的
Class
,对象实例指的是Object
。
在SpringApplication的构造方法中,有这么一行代码:
this.webApplicationType = WebApplicationType.deduceFromClasspath();
在SpringApplication的实例run()
方法中,有如下的方法的调用:
context = createApplicationContext();
在createApplicationContext()
方法,又调用了applicationContextFactory.create()
方法:
protected ConfigurableApplicationContext createApplicationContext() {
return this.applicationContextFactory.create(this.webApplicationType);
}
applicationContextFactory
成员变量定义如下:
private ApplicationContextFactory applicationContextFactory = ApplicationContextFactory.DEFAULT;
WebApplicationType
枚举定义了Spring Application的类型,有NONE
、SERVLET
和REACTIVE
三种。
在deduceFromClasspath()
方法中,使用工具方法ClassUtils.isPresent(className)
来判断特定的类是否存在,从而推断将要实例的应用类型:
static WebApplicationType deduceFromClasspath() {
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
for (String className : SERVLET_INDICATOR_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
}
org.springframework.web.reactive.DispatcherHandler
类存在时,类型为REACTIVE
;javax.servlet.Servlet
或org.springframework.web.context.ConfigurableWebApplicationContext
任一不存在时,类型为NONE
;SERVLET
。在ApplicationContextFactory
的默认实现DEFAULT
中,根据WebApplicationType
的类型,创建对应的ConfigurableApplicationContext
实例:
switch (webApplicationType) {
case SERVLET:
return new AnnotationConfigServletWebServerApplicationContext();
case REACTIVE:
return new AnnotationConfigReactiveWebServerApplicationContext();
default:
return new AnnotationConfigApplicationContext();
}
更多ApplicationContextFactory
请查看应用上下文工厂。