SpringBoot @CompentScan excludeFilters配置无效的解决方案

作者:LoWang 时间:2022-08-01 09:06:42 

@CompentScan excludeFilters配置无效

@CompentScan 注解配置需要扫描的包

excludeFilters 是其中一个配置项,用于排除不需要扫描的类

FilterType

  • ANNOTATION:根据注解来排除

  • ASSIGNABLE_TYPE:根据类类型来排除

  • ASPECTJ:根据AspectJ表达式来排除

  • REGEX:根据正则表达式来排除

  • CUSTOM:自定义FilterClass排除,需要实现org.springframework.core.type.filter.TypeFilter接口

在我们项目中,有一个core的module,里面存放了每个项目公用的package,但是有些开发人员把一些无关的初始化操作也放到了core项目中,这就导致如果A项目引用了core,那么就会做一些无用的初始化操作,由于core的子包太多,无法一个一个引用,所以使用排除法是最快的,使用REGEX进行排除操作,但是经过多次尝试,排除的类依然被spring扫描并初始化了,难道是没有效果?经过多方搜索,在这篇文章中得到启发。

Each component scan does filtering individually. While you exclude Starter.class from SimpleTestConfig, SimpleTestConfig initializes Application, which does it's own @ComponentScan without excluding Starter. The clean way of using ComponentScan is for each ComponentScan to scan separate packages, that way each filter work fine. When 2 separate ComponentScans scan the same package (as in your tests), this does not work.

每个组件扫描都会单独进行过滤 当您从SimpleTestConfig中排除Starter.class时,SimpleTestConfig会初始化Application,它会自行执行@ComponentScan而不会排除Starter。 使用ComponentScan的简洁方法是每个ComponentScan扫描单独的包,这样每个过滤器都可以正常工作。 当2个单独的ComponentScans扫描同一个包时(如在测试中),这将不起作用。

大致的意思就是说,如果你在A类中,使用了exlucde配置,在你不需要排除的类中,有某些类B的注解上也使用了@ComponentScan,但是这个类B上注解中没有进行exclude操作,那么你在A类中的exclude将不会生效。结果扫描一下core包下面的类,确实有一个类B使用@ComponentScan,那么在A类中,同时也排除类B,A类中的exclude全部生效。


@ComponentScan(
   basePackages = {"com.scio.core"},
   excludeFilters = {
     @Filter(type = FilterType.REGEX, pattern = "com\\.scio\\.core\\.B"),
     @Filter(type = FilterType.REGEX, pattern = "com\\.scio\\.core\\.message\\..*")
   })

@ComponentScan excludeFilters 自定义过滤器

一、@ComponentScan的作用

@ComponentScan用于类或接口上,主要是指定扫描路径并把带有指定注解的类注册到Spring容器中。

会被自动装配的注解包括@Component、@Bean、@Controller、@Service、@Repository等等。

二、定义组件

1. @Service注解的类

MyService类被扫描后,会生成名为myBeanService的实例


package info.pigg.study.java.service;
import org.springframework.stereotype.Service;
@Service("myBeanService")
public class MyService {
}

2. @Configuration+@Bean

MyConfig 类被扫描后,会生成名为myBeanPerson和myBeanUser两个实例


package info.pigg.study.java.config;
@Configuration
public class MyConfig {
   @Bean(name = "myBeanPerson")
   public Person myBeanPerson(){
       return new Person("king", 31);
   }
   @Bean(name = "myBeanUser")
   public User myBeanUser(){
       return new User("king", 31);
   }
}

三、在主程序类中测试

上面定义的组件都属于"info.pigg.study.java",所以添加@ComponentScan(value = “info.pigg.study.java”)


@SpringBootApplication
@ComponentScan(value = "info.pigg.study.java")
public class DictApplication {
   public static void main(String[] args) {
       ConfigurableApplicationContext run = SpringApplication.run(DictApplication.class, args);
       String[] names = run.getBeanDefinitionNames();

//打印出名称包含myBean的实例
       for (String name : names) {
           if (name.contains("myBean")) {
               System.out.println(name);
           }
       }
   }
}

测试结果如下:

myBeanService

myBeanPerson

myBeanUser

四、@ComponentScan中excludeFilters使用

在@ComponentScan可以设置includeFilters和excludeFilters,来自定义过滤器。一般excludeFilters用的比较多。

1. 过滤指定的类名

type = FilterType.ASSIGNABLE_TYPE是根据类class来过滤,后面classes指向类名


@SpringBootApplication
@ComponentScan(value = "info.pigg.study.java", excludeFilters = {
       @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {MyService.class})})
public class DictApplication {
//和上面一样,省略
}

测试结果如下:

myBeanPerson

myBeanUser

2. 过滤指定的注解

在"info.pigg.study.java"包和子包下,排除有@Service注解的类


@SpringBootApplication
@ComponentScan(value = "info.pigg.study.java", excludeFilters = {
       @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Service.class})})
public class DictApplication {
}

测试结果如下:

myBeanPerson

myBea

3. 自定义过滤

type = FilterType.CUSTOM,是自定义过滤,classes 指定的类要实现TypeFilter接口,在match方法中可以获取当前扫描到的类的信息,比如注解、类名和类路径。


@SpringBootApplication
@ComponentScan(value = "info.pigg.study.java", excludeFilters = {
       @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})})
public class DictApplication {
}

下面举例:在类名包含"MyService"时,match方法返回true,这样在excludeFilters时,包含"MyService"的类就会被排除掉。


package info.pigg.study.java.filter;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import java.io.IOException;
public class MyTypeFilter implements TypeFilter {
   @Override
   public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
       //获取当前类注解的信息
       AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();

//获取当前类资源(类的路径)
       Resource resource = metadataReader.getResource();
       ClassMetadata classMetadata = metadataReader.getClassMetadata();
       System.out.println("当前正在被扫描的类的类名" + classMetadata.getClassName());
       if (classMetadata.getClassName().contains("MyService")){
           return true;
       }
       return false;
   }
}

测试结果如下:

myBeanPerson

myBea

来源:https://www.jianshu.com/p/2cabfb1975c7

标签:SpringBoot,@CompentScan,excludeFilters
0
投稿

猜你喜欢

  • C#窗体程序实现全屏及取消全屏步骤

    2023-02-18 11:48:38
  • MyBatis学习教程(四)-如何快速解决字段名与实体类属性名不相同的冲突问题

    2023-11-25 05:43:49
  • MyBatis一二级缓存

    2021-07-03 13:01:59
  • C# Winform实现捕获窗体最小化、最大化、关闭按钮事件的方法

    2021-10-18 08:01:29
  • 使用mutex实现应用程序单实例运行代码分享

    2023-09-18 22:45:11
  • Spring源码解析之BeanPostProcessor知识总结

    2022-04-07 22:13:34
  • C# 如何调用SAP RFC

    2023-07-02 18:11:42
  • Java 数组获取最大和最小值的实例实现

    2021-06-18 15:53:06
  • Java面向对象程序设计:类的定义,静态变量,成员变量,构造函数,封装与私有,this概念与用法详解

    2022-07-12 03:35:14
  • SpringBoot定时任务动态扩展ScheduledTaskRegistrar详解

    2023-04-23 08:44:06
  • 详解解密Java中的类型转换问题

    2023-11-24 20:46:28
  • java数学工具类Math详解(round方法)

    2022-09-10 17:01:00
  • JDK 7 新特性小结实例代码解析

    2022-04-18 13:03:07
  • SpringBoot整合TomCat实现本地图片服务器代码解析

    2021-07-30 16:34:19
  • JPA 加锁机制及@Version版本控制方式

    2022-10-06 10:57:58
  • IDEA创建Java项目文件并运行教程解析

    2023-01-14 15:50:47
  • Java 字符终端上获取输入三种的方式分享

    2021-12-31 04:52:45
  • SpringBoot项目@Async方法问题解决方案

    2023-11-12 03:55:26
  • 5分钟搭建SpringCloud Eureka服务注册中心的实现

    2022-07-12 05:12:42
  • java对象拷贝常见面试题及应答汇总

    2022-01-08 00:01:52
  • asp之家 软件编程 m.aspxhome.com