SpringBoot @CompentScan excludeFilters配置無效的解決方案
@CompentScan excludeFilters配置無效
@CompentScan 注解配置需要掃描的包
excludeFilters 是其中一個配置項,用于排除不需要掃描的類
FilterType
ANNOTATION
:根據(jù)注解來排除ASSIGNABLE_TYPE
:根據(jù)類類型來排除ASPECTJ
:根據(jù)AspectJ表達式來排除REGEX
:根據(jù)正則表達式來排除CUSTOM
:自定義FilterClass排除,需要實現(xiàn)org.springframework.core.type.filter.TypeFilter接口
在我們項目中,有一個core的module,里面存放了每個項目公用的package,但是有些開發(fā)人員把一些無關(guān)的初始化操作也放到了core項目中,這就導(dǎo)致如果A項目引用了core,那么就會做一些無用的初始化操作,由于core的子包太多,無法一個一個引用,所以使用排除法是最快的,使用REGEX進行排除操作,但是經(jīng)過多次嘗試,排除的類依然被spring掃描并初始化了,難道是沒有效果?經(jīng)過多方搜索,在這篇文章中得到啟發(fā)。
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,它會自行執(zhí)行@ComponentScan而不會排除Starter。 使用ComponentScan的簡潔方法是每個ComponentScan掃描單獨的包,這樣每個過濾器都可以正常工作。 當2個單獨的ComponentScans掃描同一個包時(如在測試中),這將不起作用。
大致的意思就是說,如果你在A類中,使用了exlucde配置,在你不需要排除的類中,有某些類B的注解上也使用了@ComponentScan,但是這個類B上注解中沒有進行exclude操作,那么你在A類中的exclude將不會生效。結(jié)果掃描一下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); } } } }
測試結(jié)果如下:
myBeanService
myBeanPerson
myBeanUser
四、@ComponentScan中excludeFilters使用
在@ComponentScan可以設(shè)置includeFilters和excludeFilters,來自定義過濾器。一般excludeFilters用的比較多。
1. 過濾指定的類名
type = FilterType.ASSIGNABLE_TYPE是根據(jù)類class來過濾,后面classes指向類名
@SpringBootApplication @ComponentScan(value = "info.pigg.study.java", excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {MyService.class})}) public class DictApplication { //和上面一樣,省略 }
測試結(jié)果如下:
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 { }
測試結(jié)果如下:
myBeanPerson
myBea
3. 自定義過濾
type = FilterType.CUSTOM,是自定義過濾,classes 指定的類要實現(xiàn)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; } }
測試結(jié)果如下:
myBeanPerson
myBea
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
springBoot Junit測試用例出現(xiàn)@Autowired不生效的解決
這篇文章主要介紹了springBoot Junit測試用例出現(xiàn)@Autowired不生效的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09使用Spring?Boot如何限制在一分鐘內(nèi)某個IP只能訪問10次
有些時候,為了防止我們上線的網(wǎng)站被攻擊,或者被刷取流量,我們會對某一個ip進行限制處理,這篇文章,我們將通過Spring?Boot編寫一個小案例,來實現(xiàn)在一分鐘內(nèi)同一個IP只能訪問10次,感興趣的朋友一起看看吧2023-10-10聊聊Spring?Cloud?Gateway過濾器精確控制異常返回問題
這篇文章主要介紹了Spring?Cloud?Gateway過濾器精確控制異常返回問題,本篇任務(wù)就是分析上述現(xiàn)象的原因,通過閱讀源碼搞清楚返回碼和響應(yīng)body生成的具體邏輯,需要的朋友可以參考下2021-11-11