Web environment
下边这段话引用自官方文档
SpringApplication会尝试帮你创建正确的ApplicationContext,默认情况下会使用AnnotationConfigApplicationContext或者 AnnotationConfigEmbeddedWebApplicationContext,这取决于你开发的是否是web应用程序。
判断Web environment算法是非常简单的(基于某些类的存在与否),如果有需要的话,你可以通过setWebEnvironment(boolean webEnvironment)覆盖这种行为。
1、 通常我们启动sping boot 应用都是用SpringApplication,比如:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
2、 在SpringApplication构造方法中,最后一步调用了initialize方法
public SpringApplication(Object... sources) {
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = new HashSet();
this.initialize(sources);
}
3、而在initialize方法中,可以看到 this.webEnvironment = this.deduceWebEnvironment(); 这行代码设置SpringApplication的属性webEnvironment,deduceWebEnvironment方法是推断是否是web应用的核心方法
private void initialize(Object[] sources) {
if(sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}
this.webEnvironment = this.deduceWebEnvironment();
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
4、 接下来我们到这个方法里deduceWebEnvironment看一下,确实如描述一样,算法非常简单,判断javax.servlet.Servlet, org.springframework.web.context.ConfigurableWebApplicationContext这两个类在classpath下是否存在。
private boolean deduceWebEnvironment() {
String[] var1 = WEB_ENVIRONMENT_CLASSES;
int var2 = var1.length;
for(int var3 = 0; var3 < var2; ++var3) {
String className = var1[var3];
if(!ClassUtils.isPresent(className, (ClassLoader)null)) {
return false;
}
}
return true;
}
WEB_ENVIRONMENT_CLASSES = new String[]{
"javax.servlet.Servlet",
"org.springframework.web.context.ConfigurableWebApplicationContext"
};
5、 在SpringApplication的run方法中创建的ApplicationContext就是根据webEnvironment这个属性来判断。
public ConfigurableApplicationContext run(String... args) {
...
try {
...
context = this.createApplicationContext();
}
return context;
} catch (Throwable var9) {
...
}
}
protected ConfigurableApplicationContext createApplicationContext() {
Class contextClass = this.applicationContextClass;
if(contextClass == null) {
try {
contextClass = Class.forName(this.webEnvironment?"org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext":"org.springframework.context.annotation.AnnotationConfigApplicationContext");
} catch (ClassNotFoundException var3) {
throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
}
}
return (ConfigurableApplicationContext)BeanUtils.instantiate(contextClass);
}