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
猜你喜欢
- SpringCloud是分布式微服务架构的一站式解决方案,十多种微服务架构落地技术的集合体,俗称微服务全家桶SpringCloud和Spri
- 问题当我们数据库中的字段和实体类中的字段不一致的时候,查询会出问题数据库字段是 pwdid name pwd1 张三 1234562 李四
- 在Java移动文件夹及其所有子文件与子文件夹可以有如下的一段简单的方法来说明:public static void moveFolder(S
- 格式要求:SU MO TU WE TH FR SA &nb
- 1.接口中的默认方法和静态方法Java 8中允许接口中包含具有具体实现的方法,该方法称为 “默认方法” ,默认方法使用 default 关键
- Vector的基本介绍1.:Vector类的定义:public class Vector<E> ext
- 在学习 Spring Mvc 过程中,有必要来先了解几个关键参数:@Controller:在类上注解,则此类将编程一个控制器,在项目启动 S
- Java中的Static class详解Java中的类可以是static吗?答案是可以。在Java中我们可以有静态实例变量、静态
- 今天是开篇,得要吹一下算法,算法就好比程序开发中的利剑,所到之处,刀起头落。 针对现实中的排序问题,算法有七把利剑可以助你马道成功
- 前言文件上传是项目开发中最常见的功能之一 ,SpringMVC 可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配Multi
- java.math.BigDecimal及加减乘除计算BigDecimal简介BigDecimal用来对需要更大或更小的数进行任意精度的运算
- 用一个7 x 7的矩形表示迷宫,0和1分别表示的是通路和障碍。通过设计编写程序找到蓝色小球达到蓝色旗子的路线思路:构建一个迷宫(用二维数组)
- 本文首先将会回顾Spring 5之前的SpringMVC异常处理机制,然后主要讲解Spring Boot 2 Webflux的全局异常处理机
- 本文实例讲述了Java日期操作方法工具类。分享给大家供大家参考,具体如下:package com.gcloud.common;import
- using System;using System.Collections;using System.Xml;namespace Jb51.
- 环绕通知:它是spring框架为我们提供的一种可以在代码中手动控制增强部分什么时候执行的方式。问题:当我们配置了环绕通知之后,增强的代码执行
- ##创建测试类 新建Java工程创建测试类如下代码:(创建文件验证定时器是否执行)package makeFile;import java.
- null与voidnull值用来表示数据类型未被赋予任何值,它是一种引用类型;void表示没有类型,或者说是没有任何值。null与void的
- JavaFX主要致力于富客户端开发,以弥补swing的缺陷,主要提供图形库与media库,支持audio,video,graphic,ani
- 一、什么是 javabean ?在jsp页面中,包含html代码、css代码、java代码、以及业务逻辑处理代码等。javabean的作用就