SpringBoot 中使用自定义的 Servlet, Filter, Listener 有两种方式
1. 使用 @ServletComponentScan 定义要扫描的包目录, Servlet, Filter, Listener 可以通过 @WebServlet, @WebListener, @WebFilter 进行自动注册.
@Controller@SpringBootApplication@ComponentScan(basePackages={"com.codingos.demo","com.codingos.springbootlession1"})@ServletComponentScan(basePackages="com.codingos.springbootlession1.demo")public class SpringBootLession1Application { public static void main(String[] args) { SpringApplication.run(SpringBootLession1Application.class, args); }}
@WebServlet(name="servletDemo", urlPatterns="/servletDemo", initParams= {@WebInitParam(name="myname",value="myvalue")})public class ServletDemo extends HttpServlet {@WebFilter(servletNames="servletDemo")public class FilterDemo extends OncePerRequestFilter {@WebListenerpublic class RequestListenerDemo implements ServletRequestListener {
2. 自定义一些 Servlet, Filter, Listener, 然后在 Application 类中使用 进行注册
package com.codingos.springbootlession1;import java.util.EventListener;import java.util.HashMap;import java.util.Map;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.boot.web.servlet.ServletComponentScan;import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;import org.springframework.boot.web.servlet.ServletRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import com.codingos.springbootlession1.demo.FilterDemo2;import com.codingos.springbootlession1.demo.RequestListenerDemo2;import com.codingos.springbootlession1.demo.ServletDemo2;@Controller@SpringBootApplication@ComponentScan(basePackages={"com.codingos.demo","com.codingos.springbootlession1"})@ServletComponentScan(basePackages="com.codingos.springbootlession1.demo")public class SpringBootLession1Application { @Autowired private StringRedisTemplate template; public static void main(String[] args) { SpringApplication.run(SpringBootLession1Application.class, args); } @Bean public static ServletRegistrationBean servletRegistrationBean() { ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(); servletRegistrationBean.setServlet(new ServletDemo2()); servletRegistrationBean.setName("servletDemo2"); servletRegistrationBean.addUrlMappings("/spring-boot/servletDemo2"); servletRegistrationBean.addInitParameter("myname", "myvalue"); return servletRegistrationBean; } @Bean public static FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(new FilterDemo2()); filterRegistrationBean.addServletNames("servletDemo2"); return filterRegistrationBean; } @Bean public static ServletListenerRegistrationBeanServletListenerRegistrationBean() { ServletListenerRegistrationBean servletListenerRegistrationBean = new ServletListenerRegistrationBean<>(); servletListenerRegistrationBean.setListener(new RequestListenerDemo2()); return servletListenerRegistrationBean; }}
package com.codingos.springbootlession1.demo;import java.io.IOException;import java.io.Writer;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class ServletDemo2 extends HttpServlet { private static final long serialVersionUID = 4982760566703313419L; private String value; @Override public void init(ServletConfig config) throws ServletException { value = config.getInitParameter("myname"); super.init(config); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Writer writer = resp.getWriter(); req.getServletContext().log("ServletDemo2 doGet"); writer.write("ServletDemo2 AAAAAAA "+ value +""); //super.doGet(req, resp); }}
package com.codingos.springbootlession1.demo;import java.io.IOException;import javax.servlet.FilterChain;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.filter.OncePerRequestFilter;public class FilterDemo2 extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { ServletContext servletContext = request.getServletContext(); servletContext = getServletContext();// servletContext.log("servletDemo2 was filtered"); servletContext.log(request.getRequestURI() + "servletDemo2 was filtered"); filterChain.doFilter(request, response); }}
package com.codingos.springbootlession1.demo;import javax.servlet.ServletContext;import javax.servlet.ServletRequestEvent;import javax.servlet.ServletRequestListener;public class RequestListenerDemo2 implements ServletRequestListener { @Override public void requestInitialized(ServletRequestEvent sre) {// HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();// ServletContext servletContext = request.getServletContext(); ServletContext servletContext = sre.getServletContext(); servletContext.log("************ RequestListenerDemo2 requestInitialized ******"); } @Override public void requestDestroyed(ServletRequestEvent sre) { ServletContext servletContext = sre.getServletContext(); servletContext.log("************ RequestListenerDemo2 requestDestroyed ******"); }}
Filter 链的执行顺序
Filter1 开始
Filter2 开始
Filter3 开始
执行业务逻辑........................
Filter3 结束
Filter2 结束
Filter1 结束
在SpringBoot中, Filter 的执行顺序就是由Filter的类名决定的. 在SpringMvc中是由 web.xml 中 mapping 的先后顺序决定的. Filter的实例化顺序是倒序.