1、DisptachServlet的注册原理
(1)自动配置DisptcherServletAutoConfiguration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)@Configuration(proxyBeanMethods = false)@ConditionalOnWebApplication(type = Type.SERVLET)@ConditionalOnClass(DispatcherServlet.class)@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)public class DispatcherServletAutoConfiguration {
(2)容器中注册了一个组件DsipatcherServlet
@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)public DispatcherServlet dispatcherServlet(WebMvcProperties webMvcProperties) {DispatcherServlet dispatcherServlet = new DispatcherServlet();dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest());dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest());dispatcherServlet.setThrowExceptionIfNoHandlerFound(webMvcProperties.isThrowExceptionIfNoHandlerFound());dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents());dispatcherServlet.setEnableLoggingRequestDetails(webMvcProperties.isLogRequestDetails());return dispatcherServlet;}
(3)容器中又使用DispatcherServletRegistrationBean向容器中注册了DispatcherServlet
@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)@ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet,WebMvcProperties webMvcProperties, ObjectProvider<MultipartConfigElement> multipartConfig) {DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet,webMvcProperties.getServlet().getPath());registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());multipartConfig.ifAvailable(registration::setMultipartConfig);return registration;}
1、发现匹配的路径webMvcProperties.getServlet().getPath()=”/“
public static class Servlet { /** * Path of the dispatcher servlet. Setting a custom value for this property is not * compatible with the PathPatternParser matching strategy. */ private String path = "/";Tomcat-Servlet在匹配路径的时候 如果有多个Servlet可以匹配路径的时候,使用精确匹配优先。
2、原理
- SpringBoot应用启动发现当前是Web应用,web场景有有tomcat包
- web应用创建一个web版的ioc容器ServletWebServerApplicationContext
- ServletWebServerApplicationContext启动的时候寻找ServletWebServerFactory(Servlet的web服务器工厂->Servlet的web服务器)
- SpringBoot底层默认有很多的WebServlet服务器工厂
TomcatServletWebServerFactory,JettyServletWebServerFactory,orUndertowServletWebServerFactory - 底层直接会有一个配置类ServletWebServerFactoryAutoConfiguration
- ServletWebServerFactoryAutoConfiguration导入了ServletWebServerFactoryConfiguration(配置类)
- ServletWebServerFactoryConfiguration配置类,genuine动态判断系统中到底导入了哪个Web服务器的包(默认是web-starter导入的是Tomcat服务器),容器中就有TomcatServletWebServerFactory
- TomcatServletWebServerFactory中创建出Tomcat服务器
- 内嵌服务器,就是手动把启动武器的代码调用(tomcat核心jar要包含进来)
@Override public WebServer getWebServer(ServletContextInitializer... initializers) { if (this.disableMBeanRegistry) { Registry.disableRegistry(); } Tomcat tomcat = new Tomcat(); File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat"); tomcat.setBaseDir(baseDir.getAbsolutePath()); Connector connector = new Connector(this.protocol); connector.setThrowOnFailure(true); tomcat.getService().addConnector(connector); customizeConnector(connector); tomcat.setConnector(connector); tomcat.getHost().setAutoDeploy(false); configureEngine(tomcat.getEngine()); for (Connector additionalConnector : this.additionalTomcatConnectors) { tomcat.getService().addConnector(additionalConnector); } prepareContext(tomcat.getHost(), initializers); return getTomcatWebServer(tomcat); }3、切换内置服务器
(1)查到响应的服务器启动环境
https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters
spring-boot-starter-undertow
(2)修改pom.xml配置文件,先排除tomcat,再导入对于的服务器<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency>3、定制Servlet容器
实现 WebServerFactoryCustomizer
- 修改配置文件server.xxx(推荐)
- 自定义ConfigurationServletFactory
