spring-boot-autoconfigure过滤

<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) {{catch (Throwable ex) {return context;

}protected ConfigurableApplicationContext createApplicationContext() {
//这里的this.webApplicationType就是上面的WebApplicationType.SERVLET
return this.applicationContextFactory.create(this.webApplicationType);
} 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;
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
//第一次进来webServer servletContext都是null,会进到if分支里面
if (webServer == null && servletContext == null) {
//这里只是做个标记,不用关注,跳过
StartupStep createWebServer = this.getApplicationStartup().start("spring.boot.webserver.create");
//这里就会来查找ServletWebServerFactory,也就是web容器的工厂,具体看下getWebServerFactory()方法,还是ServletWebServerApplicationContext这个类的方法
ServletWebServerFactory factory = getWebServerFactory();
createWebServer.tag("factory", factory.getClass().toString());
this.webServer = factory.getWebServer(getSelfInitializer());
createWebServer.end();
getBeanFactory().registerSingleton("webServerGracefulShutdown",
new WebServerGracefulShutdownLifecycle(this.webServer));
getBeanFactory().registerSingleton("webServerStartStop",
new WebServerStartStopLifecycle(this, this.webServer));
}
else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context", ex);
}
}
initPropertySources();
protected ServletWebServerFactory getWebServerFactory() {
// Use bean names so that we don't consider the hierarchy
//从beanFactory中查找ServletWebServerFactory类型的bean的定义返回对应bean的名字
String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
if (beanNames.length == 0) {
throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing "
+ "ServletWebServerFactory bean.");
}
if (beanNames.length > 1) {
throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple "
+ "ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
}
//这里会从beanFactory中返回bean的名字为beanNames[0],类型为ServletWebServerFactory.class的bean对象,如果当前bean还未创建,则此时就会创建bean对象并返回
return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);

posted @ 2021-09-03 09:56  v17166570219  阅读(114)  评论(0)    收藏  举报