Spring Boot 中 TypeExcludeFilter 的作用及使用示例

在Spring Boot应用程序中,TypeExcludeFilter 是一个用于过滤特定类型的组件,使之不被Spring容器自动扫描和注册为bean的工具。这在你想要排除某些类或类型(如配置类、组件等)而不希望它们参与Spring的自动装配时非常有用。

作用

通常情况下,Spring Boot应用会通过包扫描的方式自动识别并加载带有@Component, @Service, @Repository, 或者@Configuration等注解的类。然而,在一些场景下,我们可能不希望某些特定的类被自动加载,例如测试环境中的特殊实现,或者是为了优化启动速度而排除不必要的组件。此时,TypeExcludeFilter就派上用场了,它允许开发者根据类型来排除这些不需要的组件。

使用示例

假设我们有一个项目结构如下:

java 复制代码
com.example
├── config
│   └── AppConfig.java
└── service
│   ├── HelloService.java
│   └── WorldService.java
└── MyApplication.java

这两个 Service 默认都会被 SpringBootApplication 自动扫描。我们可以利用TypeExcludeFilter来确保MockService不会在非测试环境中被加载。

首先,我们需要创建一个自定义的过滤器,该过滤器继承自TypeExcludeFilter并重写matches方法来指定哪些类型应该被排除。

请注意,我们继承 TypeExcludeFilter 并重写方法而不是直接实现TypeFilter接口中的matches方法。这是因为TypeExcludeFilter 是 @SpringBootApplication 注解自动扫描时候已经默认配置的过滤器类,如下是源码片段:

java 复制代码
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
   ...
}

编写自定义过滤器

创建自定义过滤器类,继承 TypeExcludeFilter 并重写 match 方法:

java 复制代码
package com.example.filter;

import org.springframework.context.annotation.TypeExcludeFilter;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;

public class MyTypeExcludeFilter extends TypeExcludeFilter {

    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        String className = metadataReader.getClassMetadata().getClassName();
        // 根据需要设置排除逻辑,例如这里排除特定类。比如你还可以排除所有 Test开头、Demo开头这样的类。
        return className.startsWith("com.example.service.HelloService");
    }
}

注册自定义过滤器

为了确保我们的自定义过滤器能够在应用启动时生效,我们需要创建一个实现了ApplicationContextInitializer接口的类,并在此类中注册我们的过滤器。

java 复制代码
package com.example.initializer;

import com.example.filter.MyTypeExcludeFilter;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.filter.TypeFilter;

public class MyTypeExcludeFilterInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(@NonNull ConfigurableApplicationContext applicationContext) {
        applicationContext.getBeanFactory().registerSingleton("myTypeExcludeFilter", new MyTypeExcludeFilter());
    }
}

配置 spring.factories

最后一步是在META-INF/spring.factories文件中注册我们的ApplicationContextInitializer,这样它就可以在应用启动时被自动加载:

bash 复制代码
org.springframework.context.ApplicationContextInitializer=\
com.example.initializer.MyTypeExcludeFilterInitializer

这行配置告诉Spring Boot,在应用启动时,应该查找并初始化MyTypeExcludeFilterInitializer。

之所以需要在 spring.factories 中进行配置,是因为我们需要在 @ComponentScan 注解执行之前就将我们的自定义过滤器类注册到 spring 上下文中,否则自定义的类就没用了。

总结

通过上述步骤,我们成功地将TypeExcludeFilter集成到了Spring Boot应用中,并且不需要显式地编写@ComponentScan注解或修改任何现有的配置。这种方式不仅简化了代码结构,也使得我们可以更加灵活地控制哪些类型的组件应该被排除在外。


(END)

相关推荐
不会写代码的女程序猿1 分钟前
Spring Boot+Layui构建企业级电子招投标系统源码
spring boot·招投标系统·招采系统·电子招投标
qq_3646821526 分钟前
录音APP怎么切换语言?多语言版本如何使用
java·服务器·前端
Wang's Blog30 分钟前
Java 项目实战: 交友项目 - 用户体系集成:根据环信id查询用户详情
java·lua·交友
摇滚侠35 分钟前
《On Java 中文版 基础卷》阅读笔记 复用 13
java·笔记·python
2601_9689007737 分钟前
玻璃深加工的工艺窗口:4 道工序的温度与时间参数边界
android·java·javascript
薛之谦_43 分钟前
用 Java 实现阿里云式 IAM 子用户管理:架构设计与表结构详解
java·python·阿里云
甜到心里的蛋糕1 小时前
抖音评论自动回复机器人部署实践:无头 Chrome + DeepSeek + NapCat(2C2G 云主机)
java·jvm·chrome·python·抖音·deepseek
Java爱好狂.1 小时前
阿里1658页Java面试题总结(含答案)
java·后端·高并发·架构师·java面试·java面试题·java八股文
Thanks_ks1 小时前
从 0.1+0.2 不等于 0.3 说起:聊聊浮点数精度问题
java·python·数值计算·精度丢失·bigdecimal·浮点数·ieee754
海鸥-w2 小时前
区域名称同步存储实现笔记
java·笔记