为什么加了@WebFilter注解,Spring却没有给我自动注入该过滤器?(上)

简介: 为什么加了@WebFilter注解,Spring却没有给我自动注入该过滤器?

在 Spring 编程中,主要配合如下注解构建过滤器:

  • @ServletComponentScan
  • @WebFilter


那这看起来只是用上这俩注解就能继续摸鱼了呀。但上了生产后,还是能遇到花式问题:

  • 工作不起来
  • 顺序不对
  • 执行多次等


大多因为想当然觉得使用简单,没有上心。还是有必要精通过滤器执行的流程和原理。

@WebFilter 过滤器无法被自动注入

为统计接口耗时,实现一个过滤器:

1.png该过滤器标记了 @WebFilter。所以启动程序加上扫描注解 @ServletComponentScan 让其生效:

1.png

然后,提供一个 UserController:

1.png

发现应用启动失败

image.png

TimeCostFilter 看起来是个普通 Bean啊,为何不能被自动注入?

源码解析

本质上,过滤器被 @WebFilter 修饰后,TimeCostFilter 只会被包装为 FilterRegistrationBean,而 TimeCostFilter 本身只会作为一个 InnerBean 被实例化,这意味着 TimeCostFilter 实例并不会作为 Bean 注册到 Spring 容器。

image.png

所以当我们想自动注入 TimeCostFilter 时,就会失败。知道这个结论后,我们可以带着两个问题去理清一些关键的逻辑:

FilterRegistrationBean 是什么?它是如何被定义的

javax.servlet.annotation.WebFilter

image.png

所以它不属 Spring,而是 Servlet 规范。

Spring Boot 项目使用它时,Spring Boot 使用了 org.springframework.boot.web.servlet.FilterRegistrationBean 包装 @WebFilter 标记的实例。

实现上来说,即 FilterRegistrationBean#Filter 属性就是 @WebFilter 标记的实例。这点我们可以从之前给出的截图中看出端倪。


定义一个 Filter 类时,我们可能想的是,会自动生成它的实例,然后以 Filter 的名称作为 Bean 名来指向它。

但调试发现,在 Spring Boot 中,Bean 名字确实是对的,只是 Bean 实例其实是 FilterRegistrationBean。


这 FilterRegistrationBean 最早是如何获取的呢?


得追溯到 @WebFilter 注解是如何被处理的。

@WebFilter 是如何工作的

使用 @WebFilter 时,Filter 被加载有两个条件:

  • 声明了 @WebFilter
  • 在能被 @ServletComponentScan 扫到的路径下

直接搜索对 @WebFilter 的使用,可发现 WebFilterHandler 使用了它:

image.png

因此,我们选择在 doHandle() 打断点

image.png

目录
相关文章
|
2月前
|
缓存 监控 Java
SpringBoot @Scheduled 注解详解
使用`@Scheduled`注解实现方法周期性执行,支持固定间隔、延迟或Cron表达式触发,基于Spring Task,适用于日志清理、数据同步等定时任务场景。需启用`@EnableScheduling`,注意线程阻塞与分布式重复问题,推荐结合`@Async`异步处理,提升任务调度效率。
513 128
|
1月前
|
缓存 安全 Java
《深入理解Spring》过滤器(Filter)——Web请求的第一道防线
Servlet过滤器是Java Web核心组件,可在请求进入容器时进行预处理与响应后处理,适用于日志、认证、安全、跨域等全局性功能,具有比Spring拦截器更早的执行时机和更广的覆盖范围。
|
1月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
358 2
|
2月前
|
XML Java 数据格式
常用SpringBoot注解汇总与用法说明
这些注解的使用和组合是Spring Boot快速开发和微服务实现的基础,通过它们,可以有效地指导Spring容器进行类发现、自动装配、配置、代理和管理等核心功能。开发者应当根据项目实际需求,运用这些注解来优化代码结构和服务逻辑。
290 12
|
2月前
|
Java 测试技术 数据库
使用Spring的@Retryable注解进行自动重试
在现代软件开发中,容错性和弹性至关重要。Spring框架提供的`@Retryable`注解为处理瞬时故障提供了一种声明式、可配置的重试机制,使开发者能够以简洁的方式增强应用的自我恢复能力。本文深入解析了`@Retryable`的使用方法及其参数配置,并结合`@Recover`实现失败回退策略,帮助构建更健壮、可靠的应用程序。
341 1
使用Spring的@Retryable注解进行自动重试
|
2月前
|
传感器 Java 数据库
探索Spring Boot的@Conditional注解的上下文配置
Spring Boot 的 `@Conditional` 注解可根据不同条件动态控制 Bean 的加载,提升应用的灵活性与可配置性。本文深入解析其用法与优势,并结合实例展示如何通过自定义条件类实现环境适配的智能配置。
182 0
探索Spring Boot的@Conditional注解的上下文配置
|
2月前
|
智能设计 Java 测试技术
Spring中最大化@Lazy注解,实现资源高效利用
本文深入探讨了 Spring 框架中的 `@Lazy` 注解,介绍了其在资源管理和性能优化中的作用。通过延迟初始化 Bean,`@Lazy` 可显著提升应用启动速度,合理利用系统资源,并增强对 Bean 生命周期的控制。文章还分析了 `@Lazy` 的工作机制、使用场景、最佳实践以及常见陷阱与解决方案,帮助开发者更高效地构建可扩展、高性能的 Spring 应用程序。
130 0
Spring中最大化@Lazy注解,实现资源高效利用
|
2月前
|
Java 测试技术 编译器
@GrpcService使用注解在 Spring Boot 中开始使用 gRPC
本文介绍了如何在Spring Boot应用中集成gRPC框架,使用`@GrpcService`注解实现高效、可扩展的服务间通信。内容涵盖gRPC与Protocol Buffers的原理、环境配置、服务定义与实现、测试方法等,帮助开发者快速构建高性能的微服务系统。
547 0
|
Java API Spring
Spring容器如何使用一个注解来指定一个类型为配置类型
Spring容器如何使用一个注解来指定一个类型为配置类型
192 0
|
9月前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
646 26