Springboot基础知识(13)- 注册Web原生组件(Servlet/Filter/Listener)
Spring Boot 默认以 Jar 包方式部署的,默认没有 web.xml,因此无法再像以前一样通过 web.xml 配置来使用 Servlet 、Filter、Listener,但 Spring Boot 提供了 2 种方式来注册这些 Web 原生组件。
(1) 通过组件扫描注册;
(2) 使用 RegistrationBean 注册。
1) 通过组件扫描注册
Servlet 3.0 提供了以下 3 个注解:
@WebServlet:用于声明一个 Servlet;
@WebFilter:用于声明一个 Filter;
@WebListener:用于声明一个 Listener。
这些注解可直接标注在对应组件上,它们与在 web.xml 中的配置意义相同。每个注解都具有与 web.xml 对应的属性,可直接配置,省去了配置 web.xml 的繁琐。
想要在 SpringBoot 中注册这些原生 Web 组件,可以使用 @ServletComponentScan 注解实现,该注解可以扫描标记 @WebServlet、@WebFilter 和 @WebListener 三个注解的组件类,并将它们注册到容器中。
注:@ServletComponentScan 注解只能标记在启动类或配置类上。
示例,在 “ Springboot基础知识(08)- spring-boot-starter-web(Web启动器)” 里 SpringbootWeb 项目基础上,代码如下。
(1) 创建 src/main/java/com/example/web/TestServlet.java 文件
1 package com.example.web; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.annotation.WebServlet; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 12 // 使用 @WebServlet 注解声明一个 Servlet 13 @WebServlet(name = "testServlet", urlPatterns = "/testServlet") 14 public class TestServlet extends HttpServlet { 15 16 @Override 17 protected void doGet(HttpServletRequest request, HttpServletResponse response) 18 throws ServletException, IOException { 19 System.out.println("TestServlet -> doGet()"); 20 21 response.setContentType("text/html;charset=UTF-8"); 22 PrintWriter writer = response.getWriter(); 23 writer.write("Spring Boot Test Servlet"); 24 writer.close(); 25 } 26 27 @Override 28 protected void doPost(HttpServletRequest req, HttpServletResponse resp) 29 30 throws ServletException, IOException { 31 // 32 } 33 34 }
(2) 创建 src/main/java/com/example/web/TestFiler.java 文件
1 package com.example.web; 2 3 import java.io.IOException; 4 import javax.servlet.Filter; 5 import javax.servlet.FilterConfig; 6 import javax.servlet.FilterChain; 7 import javax.servlet.ServletException; 8 import javax.servlet.ServletRequest; 9 import javax.servlet.ServletResponse; 10 import javax.servlet.annotation.WebFilter; 11 12 // 使用 @WebFilter 注解声明一个自定义的 Filter 13 @WebFilter(urlPatterns = ("/testServlet")) 14 public class TestFiler implements Filter { 15 @Override 16 public void init(FilterConfig filterConfig) throws ServletException { 17 System.out.println("TestFiler -> init()"); 18 } 19 @Override 20 public void doFilter(ServletRequest request, ServletResponse response, 21 FilterChain chain) throws IOException, ServletException { 22 System.out.println("TestFiler -> doFilter()"); 23 chain.doFilter(request, response); 24 } 25 @Override 26 public void destroy() { 27 System.out.println("TestFiler -> destroy()"); 28 } 29 }
(3) 创建 src/main/java/com/example/web/TestListener.java 文件
1 package com.example.web; 2 3 import javax.servlet.ServletContextEvent; 4 import javax.servlet.ServletContextListener; 5 import javax.servlet.annotation.WebListener; 6 7 // 使用 @WebListener 注解声明一个自定义的 Listener 8 @WebListener 9 public class TestListener implements ServletContextListener { 10 11 @Override 12 public void contextInitialized(ServletContextEvent sce) { 13 System.out.println("TestListener -> contextInitialized()"); 14 } 15 16 @Override 17 public void contextDestroyed(ServletContextEvent sce) { 18 System.out.println("TestListener -> contextDestroyed()"); 19 } 20 }
(4) 修改 src/main/java/com/example/App.java 文件
1 package com.example; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.boot.web.servlet.ServletComponentScan; 6 7 @ServletComponentScan 8 @SpringBootApplication 9 public class App { 10 public static void main(String[] args) { 11 SpringApplication.run(App.class, args); 12 System.out.println("Spring boot web project"); 13 } 14 }
访问 http://localhost:9090/testServlet
Spring Boot Test Servlet
控制台显示:
TestListener -> contextInitialized()
TestFiler -> init()
Spring boot web project
TestFiler -> doFilter()
TestServlet -> doGet()
2) 使用 RegistrationBean 注册
还可以在配置类中使用 RegistrationBean 来注册原生 Web 组件,不过这种方式相较于注解方式要繁琐一些。使用这种方式注册的原生 Web 组件,不再需要使用 @WebServlet 、@WebListener 和 @WebListener 等注解。
RegistrationBean 是个抽象类,负责将组件注册到 Servlet 容器中,Spring 提供了三个它的实现类,分别用来注册 Servlet、Filter 和 Listener。
(1) ServletRegistrationBean:Servlet 的注册类;
(2) FilterRegistrationBean:Filter 的注册类;
(3) ServletListenerRegistrationBean:Listener 的注册类。
可以在配置类中,使用 @Bean 注解将 ServletRegistrationBean、FilterRegistrationBean 和 ServletListenerRegistrationBean 添加 Spring 容器中,并通过它们将自定义的 Servlet、Filter 和 Listener 组件注册到容器中使用。
示例,在上文 SpringbootWeb 项目基础上,代码如下。
(1) 修改 src/main/java/com/example/web/TestServlet.java 文件
1 package com.example.web; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.annotation.WebServlet; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 12 public class TestServlet extends HttpServlet { 13 14 @Override 15 protected void doGet(HttpServletRequest request, HttpServletResponse response) 16 throws ServletException, IOException { 17 System.out.println("TestServlet -> doGet()"); 18 19 response.setContentType("text/html;charset=UTF-8"); 20 PrintWriter writer = response.getWriter(); 21 writer.write("Spring Boot Test Servlet (2)"); 22 writer.close(); 23 } 24 25 @Override 26 protected void doPost(HttpServletRequest req, HttpServletResponse resp) 27 28 throws ServletException, IOException { 29 // 30 } 31 32 }
(2) 修改 src/main/java/com/example/web/TestFiler.java 文件
1 package com.example.web; 2 3 import java.io.IOException; 4 import javax.servlet.Filter; 5 import javax.servlet.FilterConfig; 6 import javax.servlet.FilterChain; 7 import javax.servlet.ServletException; 8 import javax.servlet.ServletRequest; 9 import javax.servlet.ServletResponse; 10 import javax.servlet.annotation.WebFilter; 11 12 public class TestFiler implements Filter { 13 @Override 14 public void init(FilterConfig filterConfig) throws ServletException { 15 System.out.println("TestFiler -> init()"); 16 } 17 @Override 18 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 19 throws IOException, ServletException { 20 System.out.println("TestFiler -> doFilter()"); 21 chain.doFilter(request, response); 22 } 23 @Override 24 public void destroy() { 25 System.out.println("TestFiler -> destroy()"); 26 } 27 }
(3) 修改 src/main/java/com/example/web/TestListener.java 文件
1 package com.example.web; 2 3 import javax.servlet.ServletContextEvent; 4 import javax.servlet.ServletContextListener; 5 import javax.servlet.annotation.WebListener; 6 7 public class TestListener implements ServletContextListener { 8 9 @Override 10 public void contextInitialized(ServletContextEvent sce) { 11 System.out.println("TestListener -> contextInitialized()"); 12 } 13 14 @Override 15 public void contextDestroyed(ServletContextEvent sce) { 16 System.out.println("TestListener -> contextDestroyed()"); 17 } 18 }
(4) 创建 src/main/java/com/example/config/TestBeanConfig.java 文件
1 package com.example.config; 2 3 import java.util.Arrays; 4 import org.springframework.boot.web.servlet.FilterRegistrationBean; 5 import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; 6 import org.springframework.boot.web.servlet.ServletRegistrationBean; 7 import org.springframework.context.annotation.Bean; 8 import org.springframework.context.annotation.Configuration; 9 10 import com.example.web.TestServlet; 11 import com.example.web.TestFiler; 12 import com.example.web.TestListener; 13 14 @Configuration 15 public class TestBeanConfig { 16 17 @Bean 18 public ServletRegistrationBean servletRegistrationBean() { 19 TestServlet testServlet = new TestServlet(); 20 return new ServletRegistrationBean(testServlet, "/testServlet"); 21 } 22 23 @Bean 24 public FilterRegistrationBean filterRegistrationBean() { 25 TestFiler testFiler = new TestFiler(); 26 FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(testFiler); 27 28 // 注册需要过滤的 url 29 filterRegistrationBean.setUrlPatterns(Arrays.asList("/testServlet")); 30 return filterRegistrationBean; 31 } 32 33 @Bean 34 public ServletListenerRegistrationBean servletListenerRegistrationBean() { 35 TestListener testListener = new TestListener(); 36 return new ServletListenerRegistrationBean(testListener); 37 } 38 }
访问 http://localhost:9090/testServlet
Spring Boot Test Servlet (2)
控制台显示:
TestListener -> contextInitialized()
TestFiler -> init()
Spring boot web project
TestFiler -> doFilter()
TestServlet -> doGet()
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)