文章目录
一. 回顾
前面学习了Day43——嵌入式的Servlet容器配置(不再使用EmbeddedServletContainerCustomizer而是使用WebServerFactoryCustomizer),今天学习注册servlet的三大组件
二. 注册三大组件
分别使用ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean来注册servlet、filter、listener。
2.1 以前的注册方式
以前: 没有用SpringBoot的时候,我们注册servlet、filter、listener都是在webapp/WEB-INF目录下的 web.xml中配置的。
现在:使用SpringBoot后,只需在配置类中注册即可。三者的注册方式都是类似的,只需记住如何注册三大组件之一即可
2.2 注册Servlet
2.2.1 原理
ServletRegistrationBean是一个类,所以在配置类中直接new它出来,构造器使用有参构造器,其中要传入servlet实例以及请求路径,如下:
2.2.2 注册步骤
首先定义一个Servlet,如下:
package com.atguigu.springboot.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyServlet extends HttpServlet {
//处理get请求
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
//处理post请求
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("Hello MyServlet");
}
}
然后创建一个配置类MyServerConfig,在里面注册Servlet组件,如下:
@Configuration
public class MyServerConfig {
//注册Servlet组件
@Bean
public ServletRegistrationBean myServlet(){
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new MyServlet(), "/myServlet");
servletRegistrationBean.setLoadOnStartup(1);//组件的其他设置都可以在这里配置
return servletRegistrationBean;
}
}
2.3 注册Filter
2.3.1 原理
FilterRegistrationBean是一个类,所以在配置类中直接new它出来,构造器使用无参构造器,new出一个实例后再进行setxxx相关配置,如下:
2.2.2 注册步骤
首先定义一个Filter,如下:
package com.atguigu.springboot.filter;
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("MyFilter process...");
filterChain.doFilter(servletRequest,servletResponse );
}
}
然后在配置类MyServerConfig中注册Filter组件,如下:
@Configuration
public class MyServerConfig {
//注册Filter组件
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new MyFilter());
filterRegistrationBean.setUrlPatterns(Arrays.asList("/hello", "/myServlet"));
return filterRegistrationBean;
}
}
2.4 注册Listener
2.4.1 原理
ServletListenerRegistrationBean是一个类,所以在配置类中直接new它出来,构造器使用有参构造器传入一个Listener实例,new出一个实例后再进行setxxx相关配置,如下:
2.2.2 注册步骤
首先定义一个Listener,如下:
package com.atguigu.springboot.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("contextInitialized...web应用启动");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("contextDestroyed...当前web项目销毁");
}
}
然后在配置类MyServerConfig中注册Listener组件,如下:
@Configuration
public class MyServerConfig {
//注册Listener组件
@Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean(){
ServletListenerRegistrationBean<MyListener> registrationBean =
new ServletListenerRegistrationBean<>(new MyListener());
return registrationBean;
}
}
测试效果:
三. SpringBoot自动配置的DispatcherServlet
SpringBoot使用DispatcherServletAutoConfiguration自动配置DispatcherServlet。DispatcherServletAutoConfiguration里面使用这个方法来注册DispatcherServlet,如下:
@Bean(
name = {"dispatcherServletRegistration"}
)
@ConditionalOnBean(
value = {DispatcherServlet.class},
name = {"dispatcherServlet"}
)
public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet, WebMvcProperties webMvcProperties, ObjectProvider<MultipartConfigElement> multipartConfig) {
DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet, webMvcProperties.getServlet().getPath());
registration.setName("dispatcherServlet");
registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());
multipartConfig.ifAvailable(registration::setMultipartConfig);
return registration;
}
倒数第6行构造器中的第二参数就是默认拦截的路径,点进去看getPath()方法,如下:
public String getPath() {
return this.path;
}
点进去看path,如下:
public static class Servlet {
private String path = "/";
Servlet类是在WebMvcProperties中的静态内部类。
@ConfigurationProperties(
prefix = "spring.mvc"
)
public class WebMvcProperties {
从上面的分析,我们可以知道,假如要自己配置DispatcherServlet的拦截路径,可以在application.properties中配置spring.mvc.servlet.path=xxx