项目最近在替换之前陈旧的框架, 改用 SpringBoot 进行重构, 初接触, 暂时还没有用到 Servlet,Filter,Listener 的地方, 但在之前回顾 Servlet 的生命周期时, https://www.cnblogs.com/qq931399960/p/10283952.html, 想到 SpringBoot 如何使用原生 Servlet, 故简单调查了下.
目前 SpringBoot 官网 GA 版本为 2.1.2, 在官方文档中有对 Servlet,Filter,Listener 的具体描述
可以通过将 Servlet, Filter,Listener 注册为 Spring Bean 或者使用 @ServletComponentScan 注解扫描 Servlet 组件
一, 注册 Spring Bean 方式使用 Servlet,Filter,Listener
自定义 Servlet
- package com.demo.webtest.servlet;
- import java.io.IOException;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class MyServlet extends HttpServlet {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- doPost(req, resp);
- }
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- System.out.println("do service");
- }
- @Override
- public void destroy() {
- System.out.println("destory servlet");
- }
- @Override
- public void init() throws ServletException {
- System.out.println("init servlet");
- }
- }
自定义 Filter
- package com.demo.webtest.servlet;
- import java.io.IOException;
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- public class MyFilter implements Filter {
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
- System.out.println("do filter");
- // 使请求继续执行
- chain.doFilter(request, response);
- }
- }
自定义 Listener(以 ServletRequestListener 为例)
- package com.demo.webtest.servlet;
- import javax.servlet.ServletRequestEvent;
- import javax.servlet.ServletRequestListener;
- public class MyRequestListener implements ServletRequestListener {
- @Override
- public void requestDestroyed(ServletRequestEvent sre) {
- System.out.println("destory request");
- }
- @Override
- public void requestInitialized(ServletRequestEvent sre) {
- System.out.println("init request");
- }
- }
将自定义 Servlet,Filter,Listener 注册为 Spring Bean
- package com.demo.webtest.servletbean;
- import javax.servlet.Filter;
- import javax.servlet.Servlet;
- import javax.servlet.ServletRequestListener;
- import org.springframework.boot.Web.servlet.FilterRegistrationBean;
- import org.springframework.boot.Web.servlet.ServletListenerRegistrationBean;
- import org.springframework.boot.Web.servlet.ServletRegistrationBean;
- import org.springframework.context.annotation.Bean;
- import org.springframework.stereotype.Component;
- import com.demo.webtest.servlet.MyFilter;
- import com.demo.webtest.servlet.MyRequestListener;
- import com.demo.webtest.servlet.MyServlet;
- @Component
- public class ServletBean {
- @Bean
- public ServletRegistrationBean<Servlet> registerServlet() {
- ServletRegistrationBean<Servlet> servletRegistrationBean = new ServletRegistrationBean<Servlet>(new MyServlet(),
- "/myservlet");
- // 设置服务启动时初始化该 servlet
- servletRegistrationBean.setLoadOnStartup(1);
- return servletRegistrationBean;
- }
- @Bean
- public FilterRegistrationBean<Filter> registerFilter() {
- FilterRegistrationBean<Filter> filter = new FilterRegistrationBean<>();
- filter.setFilter(new MyFilter());
- filter.addUrlPatterns("/*");
- return filter;
- }
- @Bean
- public ServletListenerRegistrationBean<ServletRequestListener> registerRequestListener() {
- ServletListenerRegistrationBean<ServletRequestListener> servletListenerRegistrationBean = new ServletListenerRegistrationBean<>();
- servletListenerRegistrationBean.setListener(new MyRequestListener());
- return servletListenerRegistrationBean;
- }
- }
启动服务
MyServlet 设置了 loadOnStartup, 且其值大于等于 0, 故服务启动初始化 MyServlet, 调用了其 init 方法, 页面访问 http://localhost:8080/myservlet
上面日志省略...
- 2019-01-20 09:29:02.308 WARN 12592 --- [ main] ion$DefaultTemplateResolverConfiguration : Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration)
- init servlet
- 2019-01-20 09:29:02.710 INFO 12592 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
- 2019-01-20 09:29:02.712 INFO 12592 --- [ main] com.demo.webtest.WebtestApplication : Started WebtestApplication in 3.032 seconds (JVM running for 3.47)
- init request
- do filter
- do service
- destory request
1, 程序启动, 初始化 Servlet
2, 页面访问 Servlet, 初始化 request
3, 过滤器过滤请求
4, 执行 Servlet 业务
5, 销毁 request
清空日志, 再次访问 http://localhost:8080/myservlet
- init request
- do filter
- do service
- destory request
1, 初始化 request
2, 过滤器过滤请求
3, 执行 Servlet 业务
4, 销毁 request
二, 使用注解扫描 Servlet 组件
删除或注释掉 ServletBean 类
修改自定义 Servlet,Filter,Listener, 添加 Servlet 相关组件注解
自定义 Servlet, 为与上面区分, 将 url 将映射到 / my
- package com.demo.webtest.servlet;
- import java.io.IOException;
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- @WebServlet(urlPatterns = "/my", loadOnStartup = 0)
- public class MyServlet extends HttpServlet {
- ...
- }
自定义 Filter
- package com.demo.webtest.servlet;
- import java.io.IOException;
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.annotation.WebFilter;
- @WebFilter(urlPatterns="/*")
- public class MyFilter implements Filter {
- ...
- }
自定义 Listener
- package com.demo.webtest.servlet;
- import javax.servlet.ServletRequestEvent;
- import javax.servlet.ServletRequestListener;
- import javax.servlet.annotation.WebListener;
- @WebListener(value="/*")
- public class MyRequestListener implements ServletRequestListener {
- ...
- }
启动类添加 Servlet 组件扫描
- package com.demo.webtest;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.boot.Web.servlet.ServletComponentScan;
- @SpringBootApplication
- @ServletComponentScan
- public class WebtestApplication {
- public static void main(String[] args) {
- SpringApplication springApplication = new SpringApplication(WebtestApplication.class);
- springApplication.run(args);
- }
- }
服务启动, 也会先进行 servlet 初始化, 页面访问 http://localhost:8080/my, 日志输出与上述注册 Spring Bean 方式一致
来源: http://www.bubuko.com/infodetail-2927453.html