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)

相关推荐
腾渊信息科技公司17 分钟前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地1 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
莫逸风4 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
隔窗听雨眠4 小时前
Spring Boot在云原生时代的编程范式革新研究
spring boot·后端·云原生
z123456789864 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
yaoxin5211235 小时前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python
做个文艺程序员5 小时前
Linux第24篇:Java应用监控体系搭建:Prometheus+Grafana可视化运维
java·grafana·prometheus
小钻风33666 小时前
Spring Boot 文件上传详解:深入理解 MultipartFile 的使用与原理
java·开发语言
其美杰布-富贵-李6 小时前
Spring Boot 工程开发全流程说明
java·spring boot·后端
前端双越老师8 小时前
如何以前端视角(非0基础)学 Java ?
java·node.js·全栈