SpringBoot的WebServlet的兼容
一.使用SpringBean注册JavaWeb的三大组件
在 Spring Boot 中,使用 @Bean 注册的 Servlet、Filter 和 Listener 组件会被加载到 Servlet 容器 中管理,而不是直接由 Spring 容器管理。然而,Spring Boot 提供了一些机制来确保这些组件能够与 Spring 容器无缝集成。
- Servlet 容器:负责处理 HTTP 请求和响应,如 Tomcat、Jetty 或 Undertow。
- Spring 容器:负责管理 Spring 应用程序中的 Bean 生命周期和依赖注入。
注册 Servlet、Filter 和 Listener
- 当你在 Spring Boot 配置类中使用 @Bean 注册 Servlet、Filter 和 Listener 时,Spring Boot 会将这些组件注册到嵌入式的 Servlet 容器中。
- 这些组件仍然可以通过 Spring 的依赖注入机制获得其他 Spring 管理的 Bean,但它们的实际生命周期和调用是由 Servlet 容器管理的。
使用JavaWeb中的组件需要导入相关的依赖,但是如果springBoot导入的springWeb的依赖就不需要这么麻烦了,因为SpringWeb内置了JavaWeb中的组件,即向下兼容
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
Servlet组件
在 Java Web 开发中,Servlet 是一个核心组件,用于处理客户端(通常是浏览器)发送的 HTTP 请求,并生成相应的响应。Servlet 是 Java 平台上的服务器端程序,运行在支持 Java 的应用服务器或 Servlet 容器
- Servlet 是 Java Web 应用程序的核心组件,负责处理 HTTP 请求并生成响应。
- Servlet 的生命周期包括初始化、服务和销毁阶段,由 Servlet 容器管理。
- 可以通过注解(如 @WebServlet)或 web.xml 文件来配置 Servlet。
- Servlet 可以与 Spring 容器集成,利用 Spring 的依赖注入和其他功能
使用示例:
Servlet1
//继承HttpServlet public class servlet1 extends HttpServlet { // 重写doGet方法 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 输出hello,Servlet1 System.out.println("hello,Servlet1"); // 将hello,Servlet1写入响应 resp.getWriter().write("hello,Servlet1"); } }
Servlet2
//继承HttpServlet类 public class Servlet2 extends HttpServlet { //重写doGet方法 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("hello,servlet2"); resp.getWriter().write("hello,servlet2"); } }
使用config类注入Bean
@Configuration public class CreateBean { @Bean public servlet1 creates1(){ return new servlet1(); } @Bean public Servlet2 creates2(){ return new Servlet2(); } }
结果1:
结果2:
注意点:
如果出现访问不了的情况可以去看我的另外一篇博客:SpringBoot集成WebServlet出现自定义单servlet请求失败的问题
Filter组件
在 Java Web 开发中,Filter(过滤器) 是一个重要的组件,用于拦截和处理 HTTP 请求和响应。过滤器可以在请求到达目标 Servlet 之前或响应返回给客户端之前执行一些预处理或后处理操作。这使得过滤器成为实现横切关注点
- Filter 是 Java Web 应用程序中的一个重要组件,用于拦截和处理 HTTP 请求和响应。
- 过滤器可以在请求到达目标 Servlet 之前或响应返回给客户端之前执行预处理或后处理操作。
- 过滤器的生命周期包括初始化和销毁阶段,由 Servlet 容器管理。
- 可以通过注解(如
@WebFilter
)或web.xml
文件来配置过滤器。 - 过滤器适用于实现横切关注点,如日志记录、认证、压缩等。
使用示例:
创建Filter类:
//实现Filter接口 public class MyFilter implements Filter { // 实现Filter接口,重写doFilter方法 @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 打印进入filter的提示信息 System.out.println("进入filter!"); // 调用FilterChain的doFilter方法,继续执行下一个过滤器或目标资源 filterChain.doFilter(servletRequest,servletResponse); // 打印出filter的提示信息 System.out.println("出filter!"); } }
注册Bean:
@Bean public MyFilter createFilter(){ return new MyFilter(); }
发起一个请求之后的控制台输出:
Listener组件
在 Java Web 开发中,Listener(监听器) 是一种用于监听和响应特定事件的组件。这些事件通常与 Servlet 上下文(ServletContext)、HTTP 会话(HttpSession)或请求(ServletRequest)的生命周期相关。监听器允许你在这些事件发生时执行自定义逻辑
监听 Servlet 上下文事件
- Context Initialization: 当 Web 应用程序启动时触发。
- Context Destruction: 当 Web 应用程序停止时触发。
- Attribute Changes: 监听 ServletContext 属性的变化(添加、删除、替换)。
使用示例
Java代码:
//实现ServletContextListener接口 public class MyListener implements ServletContextListener { // 实现ServletContextListener接口,用于监听Web应用的初始化和销毁事件 @Override public void contextInitialized(ServletContextEvent sce) { // 当Web应用初始化完成时,执行该方法 System.out.println("---Web应用初始化完成---"); } @Override public void contextDestroyed(ServletContextEvent sce) { // 当Web应用销毁前,执行该方法 System.out.println("---Web应用销毁前---"); } }
使用config类注入:
@Bean public MyListener createListener(){ return new MyListener(); }
结果:
springBoot服务启动时
springBoot服务关闭时
二.其它注入JavaWeb组件的方式
RegistrationBean注入
在前面的配置都不变的情况下,清空config文件中的注入Bean的方式,修改为
@Configuration @SuppressWarnings("all") public class CreateBean { // 创建一个名为s1的ServletRegistrationBean,映射路径为"/s1" @Bean public ServletRegistrationBean s1(){ return new ServletRegistrationBean(new servlet1(),"/s1"); } // 创建一个名为s2的ServletRegistrationBean,映射路径为"/s2" @Bean public ServletRegistrationBean s2(){ return new ServletRegistrationBean(new Servlet2(),"/s2"); } // 创建一个名为f1的FilterRegistrationBean,映射路径为"/s1" @Bean public FilterRegistrationBean f1(){ FilterRegistrationBean bean = new FilterRegistrationBean(new MyFilter()); bean.setUrlPatterns(Arrays.asList("/s1")); return bean; } // 创建一个名为l1的ServletListenerRegistrationBean @Bean public ServletListenerRegistrationBean l1(){ return new ServletListenerRegistrationBean(new MyListener()); } }
测试结果(三个组件一起):
注解声明式注入
这里可以将config配置类整个都删掉,我们将使用新的方式来完成注入
@WebServlet @WebFilter @WebListener
servlet1:
@WebServlet("/s1") //继承HttpServlet public class servlet1 extends HttpServlet { // 重写doGet方法 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 输出hello,Servlet1 System.out.println("hello,Servlet1"); // 将hello,Servlet1写入响应 resp.getWriter().write("hello,Servlet1"); } }
servlet2:
@WebServlet("/s2") //继承HttpServlet类 public class Servlet2 extends HttpServlet { //重写doGet方法 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("hello,servlet2"); resp.getWriter().write("hello,servlet2"); } }
Filter:
@WebFilter //实现Filter接口 public class MyFilter implements Filter { // 实现Filter接口,重写doFilter方法 @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 打印进入filter的提示信息 System.out.println("进入filter!"); // 调用FilterChain的doFilter方法,继续执行下一个过滤器或目标资源 filterChain.doFilter(servletRequest,servletResponse); // 打印出filter的提示信息 System.out.println("出filter!"); } }
Listener:
@WebListener //实现ServletContextListener接口 public class MyListener implements ServletContextListener { // 实现ServletContextListener接口,用于监听Web应用的初始化和销毁事件 @Override public void contextInitialized(ServletContextEvent sce) { // 当Web应用初始化完成时,执行该方法 System.out.println("---Web应用初始化完成---"); } @Override public void contextDestroyed(ServletContextEvent sce) { // 当Web应用销毁前,执行该方法 System.out.println("---Web应用销毁前---"); } }
最后记得在启动器上追加上@ServletComponetScan注解,加上之后才会在spring容器启动后进行自动扫描
@SpringBootApplication @ServletComponentScan public class SpringBoot01Application { public static void main(String[] args) { SpringApplication.run(SpringBoot01Application.class, args); } }
结果(三个组件一起):
----END----