一、 剖析SpringBoot自动配置嵌入式Servlet
在Spring以前,如果我们写一个web应用,我们最终可能需要将一个web应用打成一个war包,然后我们还需要在外部配置好Tomcat环境,而这个Tomcat就是一个Servlet容器,然后把这个war包放在Tomcat上,我们在Tomcat上启动就可以了。
而SpringBoot中,我们无须配置一个Tomcat服务器,我们直接运行就可以了,这就是嵌入式的Servlet容器。
SpringBoot默认的使用的是嵌入式的Servlet容器(Tomcat)。
问题?
1)使用外部的Tomcat,可以使用外部配置文件修改,而在嵌入式Servlet容器中
① 修改Server有关的配置,ServerProperties
server.servlet.context-path=/crud
server.port=8081
server.tomcat.uri-encoding=utf-8
//通用的Servlet容器设置
server.xxx
//Tomcat的设置
server.tomcat.xxx
② 编写一个EmbeddedServletContainerCustomizer:嵌入式的Servlet容器的定制器,来修改Servlet容器的配置,注意:SpringBoot2.0以上WebServerFactoryCustomizer给取代了。
@Bean
public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer(){
return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
@Override
public void customize(ConfigurableWebServerFactory factory) {
factory.setPort(8083);
}
}
}
二、注册Servlet、Filter和Listener
由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,没有web.xml文件。
要注册三大组件用以下方式:
ServletRegistrationBean
@Bean
public ServletRegistrationBean myServlet(){
ServletRegistrationBean<Servlet> servletServletRegistrationBean = new ServletRegistrationBean<>(new MyServlet(),"/myServlet");
return servletServletRegistrationBean;
}
FilterRegistrationBean
@Bean
public FilterRegistrationBean myFilter(){
FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>();
filterFilterRegistrationBean.setFilter(new MyFilter());
filterFilterRegistrationBean.setUrlPatterns(Arrays.asList("/myServlet","/hello"));
return filterFilterRegistrationBean;
}
ServletListenerRegistrationBean
@Bean
public ServletListenerRegistrationBean myListener(){
ServletListenerRegistrationBean<MyListener> listener = new ServletListenerRegistrationBean<MyListener>(new MyListener());
return listener;
}
SpringBoot帮我们自动配置SpringMVC的时候,自动的注册SpringMVC的前端控制器:DispatcherServlet
public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet, WebMvcProperties webMvcProperties, ObjectProvider<MultipartConfigElement> multipartConfig) {
DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet, webMvcProperties.getServlet().getPath());
//默认拦截: / 所有请求,包括静态资源,但是不拦截jsp请求,/*会拦截jsp
//可以通过server.servletPath来修改SpringMVC前端控制器默认拦截的请求
registration.setName("dispatcherServlet");
registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());
multipartConfig.ifAvailable(registration::setMultipartConfig);
return registration;
}
public String getServletMapping() {
if (!this.path.equals("") && !this.path.equals("/")) {
return this.path.endsWith("/") ? this.path + "*" : this.path + "/*";
} else {
return "/";
}
}
三、使用其他Servlet容器
ctrl+h
打开目录树
Tomcat(默认)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Jetty(长连接)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入其他的Servlet容器-->
<dependency>
<artifactId>spring-boot-starter-jetty</artifactId>
<groupId>org.springframework.boot</groupId>
</dependency>
Undertow(不支持JSP应用)
<dependency>