SpringBoot中TypeExcludeFilter的作用及使用方式
作者:catoop
SpringBoot中TypeExcludeFilter的作用及使用
在Spring Boot应用程序中,TypeExcludeFilter 是一个用于过滤特定类型的组件,使之不被Spring容器自动扫描和注册为bean的工具。
这在你想要排除某些类或类型(如配置类、组件等)而不希望它们参与Spring的自动装配时非常有用。
作用
通常情况下,Spring Boot应用会通过包扫描的方式自动识别并加载带有@Component, @Service, @Repository, 或者@Configuration等注解的类。
然而,在一些场景下,我们可能不希望某些特定的类被自动加载,例如测试环境中的特殊实现,或者是为了优化启动速度而排除不必要的组件。
此时,TypeExcludeFilter就派上用场了,它允许开发者根据类型来排除这些不需要的组件。
使用示例
假设我们有一个项目结构如下:
com.example ├── config │ └── AppConfig.java └── service │ ├── HelloService.java │ └── WorldService.java └── MyApplication.java
这两个 Service 默认都会被 SpringBootApplication 自动扫描。
我们可以利用TypeExcludeFilter来确保MockService不会在非测试环境中被加载。
首先,我们需要创建一个自定义的过滤器,该过滤器继承自TypeExcludeFilter并重写matches方法来指定哪些类型应该被排除。
请注意:
- 我们继承
TypeExcludeFilter并重写方法而不是直接实现TypeFilter接口中的matches方法。 - 这是因为
TypeExcludeFilter是@SpringBootApplication注解自动扫描时候已经默认配置的过滤器类
如下是源码片段:
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}编写自定义过滤器
创建自定义过滤器类,继承 TypeExcludeFilter 并重写 match 方法:
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接口的类,并在此类中注册我们的过滤器。
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,这样它就可以在应用启动时被自动加载:
org.springframework.context.ApplicationContextInitializer=\ com.example.initializer.MyTypeExcludeFilterInitializer
这行配置告诉Spring Boot,在应用启动时,应该查找并初始化MyTypeExcludeFilterInitializer。
之所以需要在 spring.factories 中进行配置,是因为我们需要在 @ComponentScan 注解执行之前就将我们的自定义过滤器类注册到 spring 上下文中,否则自定义的类就没用了。
总结
通过上述步骤,我们成功地将TypeExcludeFilter集成到了Spring Boot应用中,并且不需要显式地编写@ComponentScan注解或修改任何现有的配置。
这种方式不仅简化了代码结构,也使得我们可以更加灵活地控制哪些类型的组件应该被排除在外。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
- 如何解决springboot启动的时候required a bean of type 'XXX' not be问题
- SpringBoot中MyBatis使用自定义TypeHandler的实现
- SpringBoot3.1.2 引入Swagger报错Type javax.servlet.http.HttpServletRequest not present解决办法
- SpringBoot升级3.2报错Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String的解决方案
- 解决springboot+thymeleaf视图映射报错There was an unexpected error (type=Not Found, status=404)
