web容器源码分析
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
public static void main(String[] args) {
SpringApplication.run(BootargsApplication.class,args);
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class<?>[] { primarySource }, args);
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
public SpringApplication(Class<?>... primarySources) {
this(null, primarySources);
@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
......
//本次不相关的代码全部省略掉,只保留相关代码
//这里的 this.webApplicationType=WebApplicationType.SERVLET, 我们来分析下这个代码的具体的执行赋值
this.webApplicationType = WebApplicationType.deduceFromClasspath();
/这个方法主要是在当前类路径下查找指定的class类是否存在,返回对饮枚举类型
static WebApplicationType deduceFromClasspath() {
// WEBMVC_INDICATOR_CLASS = "org.springframework.web.servlet.DispatcherServlet";
//我们通过pom文件引入spring-boot-starter-web,会简介引入spring-webmvc,上面这个类就在这个webmvc中,所以不会进入这个if分支
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
//SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet",
"org.springframework.web.context.ConfigurableWebApplicationContext" }
//javax.servlet.Servlet这个类存在于tomcat-embed-core中
//org.springframework.web.context.ConfigurableWebApplicationContext这个类存在于spring-web中
//这两个jar都是由spring-boot-starter-web间接引入的,所以也不会走这个分支
for (String className : SERVLET_INDICATOR_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
//所以会从这里返回
return WebApplicationType.SERVLET;
public ConfigurableApplicationContext run(String... args) {
.......
try {
......
//我们来看这个context的创建,context=new AnnotationConfigServletWebServerApplicationContext()下面来具体看这块的执行
context = createApplicationContext();
......
//后续几个部分会来说明这个方法
refreshContext(context);
......
}
catch (Throwable ex) {
......
}
try {
.......
}
catch (Throwable ex) {
.......
}
return context;
ApplicationContextFactory DEFAULT = (webApplicationType) -> {
try {
switch (webApplicationType) {
case SERVLET:
//会从这里返回
return new AnnotationConfigServletWebServerApplicationContext();
case REACTIVE:
return new AnnotationConfigReactiveWebServerApplicationContext();
default:
return new AnnotationConfigApplicationContext();
}
}
catch (Exception ex) {
throw new IllegalStateException("Unable create a default ApplicationContext instance, "
+ "you may need a custom ApplicationContextFactory", ex);
private void refreshContext(ConfigurableApplicationContext context) {
if (this.registerShutdownHook) {
shutdownHook.registerApplicationContext(context);
}
refresh(context);
public final void refresh() throws BeansException, IllegalStateException {
try {
//继续跳转到父类AbstractApplicationContext方法
super.refresh();
}
catch (RuntimeException ex) {
WebServer webServer = this.webServer;
if (webServer != null) {
webServer.stop();
}
throw ex;