SpringBoot 默认使用的嵌入式 Servlet 容器为 Tomcat,通过依赖关系就可以看到:
问题:
- 如何定制和修改 Servlet 容器相关配置?
- SpringBoot 能否支持其它 Servlet 容器?
配置 Servlet 容器
配置文件
在普通 Web 程序中我们如果需要修改 Tomcat 配置则可通过 Tomcat 目录下 conf/server.xml
修改,而在 SpringBoot 中我们只需要在项目配置文件中通过 server
节下的相关属性即可修改容器相关配置,如:
# 通用 Servlet 容器配置
server.port=8080
server.context-path=/
# Tomcat 配置
server.tomcat.uri-encoding=utf-8
容器的定制器
除了上述配置的方式,SpringBoot 还为我们提供了嵌入式 Servlet 容器的定制器类来定制相关配置,例:
@Bean
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
return new EmbeddedServletContainerCustomizer() {
// 定制嵌入式 Servlet 容器相关规则
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
// container 即为容器对象
container.setPort(8088);
}
};
}
配置文件中 server
节对应的配置属性类内部也是通过该方式定义容器配置的。
三大组件的注册
如果是在一个标准的 Web 工程中,我们可以通过 WEB-INF/web.xml
来注册三大组件,即 Servlet、Filter、Listener。而 SpringBoot 项目默认是以 jar 包的方式通过嵌入式的 Servlet 容器来启动 web 应用,没有 web.xml
,注册三大组件则需要按照以下方式:
注册 Servlet-ServletRegistrationBean
@Bean
public ServletRegistrationBean myServlet(){
return new ServletRegistrationBean(new MyServlet(), "/servlet/hello");
}
注册 Filter-FilterRegistrationBean
@Bean
public FilterRegistrationBean myFilter(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new MyFilter());
filterRegistrationBean.setUrlPatterns(Arrays.asList("/servlet/hello","/login"));
return filterRegistrationBean;
}
注册 Listener-ListenerRegistrationBean
@Bean
public ServletListenerRegistrationBean myListener(){
return new ServletListenerRegistrationBean(new MyListener());
}
SpringMVC 的核心 Servlet 在 SpringBoot 中就是以此种方式注册,如下:
// org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration
@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet() {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.setDispatchOptionsRequest(
this.webMvcProperties.isDispatchOptionsRequest());
dispatcherServlet.setDispatchTraceRequest(
this.webMvcProperties.isDispatchTraceRequest());
dispatcherServlet.setThrowExceptionIfNoHandlerFound(
this.webMvcProperties.isThrowExceptionIfNoHandlerFound());
return dispatcherServlet;
}
@Configuration
@Conditional(DispatcherServletRegistrationCondition.class)
@ConditionalOnClass(ServletRegistration.class)
@EnableConfigurationProperties(WebMvcProperties.class)
@Import(DispatcherServletConfiguration.class)
protected static class DispatcherServletRegistrationConfiguration {
private final ServerProperties serverProperties;
private final WebMvcProperties webMvcProperties;
private final MultipartConfigElement multipartConfig;
public DispatcherServletRegistrationConfiguration(
ServerProperties serverProperties, WebMvcProperties webMvcProperties,
ObjectProvider<MultipartConfigElement> multipartConfigProvider) {
this.serverProperties = serverProperties;
this.webMvcProperties = webMvcProperties;
this.multipartConfig = multipartConfigProvider.getIfAvailable();
}
@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
@ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public ServletRegistrationBean dispatcherServletRegistration(
DispatcherServlet dispatcherServlet) {
ServletRegistrationBean registration = new ServletRegistrationBean(
dispatcherServlet, this.serverProperties.getServletMapping());
registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
registration.setLoadOnStartup(
this.webMvcProperties.getServlet().getLoadOnStartup());
if (this.multipartConfig != null) {
registration.setMultipartConfig(this.multipartConfig);
}
return registration;
}
}
评论区