Spring中的@ComponentScan注解詳解
Spring注解 @ComponentScan
1.添加 @ComponentScan 注解
創(chuàng)建一個配置類,在配置類上添加 @ComponentScan 注解。該注解默認會掃描該類所在的包下所有的配置類,相當于之前的
<context:component-scan>
2.獲取已經(jīng)注冊到容器中的 bean 的名稱以及數(shù)量
使用 ApplicationContext 的 getBeanDefinitionNames() 方法和getBeanDefinitionCount()獲取已經(jīng)注冊到容器中的 bean 的名稱以及數(shù)量
@SpringBootApplication public class ZzyNotesApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(ZzyNotesApplication.class, args); String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String beanName : beanDefinitionNames) { System.out.println("beanName: " + beanName); } System.out.println("bean總數(shù):"+context.getBeanDefinitionCount()); } }
3.@ComponentScan
@SpringBootApplication注解中已經(jīng)存在,也可以根據(jù)需要自定義 @SpringBootApplication(scanBasePackages = "")
常用參數(shù):
1.value || basePackages = "包路徑,默認當前類所在包"
2.excludeFilters 使用 excludeFilters 來按照規(guī)則排除某些包的掃描。
3.includeFilters 用includeFilters配置 掃描的類
優(yōu)先級由上之下,比如自定義的MyTypeFilter如果已經(jīng)Bean已經(jīng)在ioc容器中,或者上面的excludeFilters已經(jīng)過濾掉這個Bean,則不掃描這個類
- 參數(shù):
- FilterType.ANNOTATION :注解名規(guī)則,Service.class
- FilterType.ASSIGNABLE_TYPE : 按照給定的類型,比如當前類型的父子類。
- FilterType.ASPECTJ :使用aspectj表達式
- FilterType.REGEX :使用正則指定
- FilterType.CUSTOM
4.useDefaultFilters
默認為true ,會優(yōu)先執(zhí)行默認的過濾器 對 @Component、@ManagedBean、@Named注解的Bean進行掃描 所以要改為false
配置類代碼如下
@Configuration @ComponentScans( { @ComponentScan(value = "com.zzy.zzyNotes" ,useDefaultFilters = false), @ComponentScan(value = "com.zzy.zzyNotes.spring.createBean", excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Service.class}),//排除包含注解Service的類(不生效,原因未知) @ComponentScan.Filter(type = FilterType.ANNOTATION, value = {ExcludeMyAnnotation.class})//排除包含注解MyAnnotation2的類 }, includeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {IncludeMyAnnotation.class}),//指定掃描包換注解MyAnnotation的類 @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class}),//指定注解掃描包換注解Controller的類 @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE , classes = {Person2.class}),//指定類型Person2的類 @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})//自定義過濾規(guī)則 } , useDefaultFilters = false//這個沒有效果,必須在啟動類上的@ComponentScan( useDefaultFilters = false)中配置 false ) } ) public class BeanConfig { }
/** * @author zzy * @createDate: 2021-12-30 16:26:50 * @description: 自定義注解 指定某個類被掃描 */ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface IncludeMyAnnotation { }
/** * @author zzy * @createDate: 2021-12-30 16:26:50 * @description: 自定義注解 排除某個類被掃描 */ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ExcludeMyAnnotation { }
/** * 掃描包自定義規(guī)則 * metadataReader:讀取到當前正在掃描類的信息 * metadataReaderFactory:可以獲取到其他任何類的信息 * 注意:只有不滿足其它的規(guī)則,才會被自定義過濾規(guī)則判斷 * @author zzy */ public class MyTypeFilter implements TypeFilter { /** * @description: 掃描規(guī)則 * @params: * @return: 返回true 加入IOC容器 false ,排除 */ @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //獲取當前類注解信息 AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); //獲取當前正在掃描類的信息 ClassMetadata classMetadata = metadataReader.getClassMetadata(); //獲取當前類資源信息 (比如類存在哪個盤,類的路徑 ) Resource resource = metadataReader.getResource(); String name = classMetadata.getClassName(); System.out.println("Filter掃描的類名:" + name); if(name.contains("Person3")){ return true; } return false; } }
/** * @author zzy * @createDate: 2021-12-30 10:08:35 * @description: 創(chuàng)建Bean Person1 加IncludeMyAnnotation */ @IncludeMyAnnotation public class Person1 { }
/** * @author zzy * @createDate: 2021-12-30 10:10:37 * @description: 創(chuàng)建Bean Person1 加@ExcludeMyAnnotation 被排除 * 正常有@Component就會被掃描,加了@ExcludeMyAnnotation就會被排除 */ @ExcludeMyAnnotation @Component public class Person2 { }
/** * @author zzy * @createDate: 2021-12-30 17:03:44 * @description: 創(chuàng)建Bean Person3 符合MyTypeFilter過濾規(guī)則 */ public class Person3 { }
其他問題
優(yōu)先級
- 自定義的@ComponentScan優(yōu)先級大于@SpringBootApplication默認的,要注意的是,
- 自定義的@ComponentScan的路徑一定要包含啟動類項目路徑,默認為配置類所在的路徑
注意
1.自定義@ComponentScan時注意控制的路徑范圍
2.有重名的Bean會注冊失敗
問題
spring 有默認的規(guī)律規(guī)則 會對 @Component、@ManagedBean、@Named注解的Bean進行掃描,如果設(shè)置了
excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Service.class})
但是加了@service的類依然被注冊到ioc
所以要設(shè)置 useDefaultFilters = false
到此這篇關(guān)于Spring中的@ComponentScan注解詳解的文章就介紹到這了,更多相關(guān)@ComponentScan注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IDEA設(shè)置字體隨鼠標滾動放大縮小的實現(xiàn)
這篇文章主要介紹了IDEA設(shè)置字體隨鼠標滾動放大縮小的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01Spring?Data?JPA實現(xiàn)審計功能過程詳解
Spring?Data?JPA為跟蹤持久性層的變化提供了很好的支持。通過使用審核,我們可以存儲或記錄有關(guān)實體更改的信息,例如誰創(chuàng)建或更改了實體以及何時進行更改2023-02-02使用mybatis的interceptor修改執(zhí)行sql以及傳入?yún)?shù)方式
這篇文章主要介紹了使用mybatis的interceptor修改執(zhí)行sql以及傳入?yún)?shù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12使用JVMTI實現(xiàn)SpringBoot的jar加密,防止反編譯
這篇文章主要介紹了使用JVMTI實現(xiàn)SpringBoot的jar加密,防止反編譯問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08java中@JsonFormat和@JSONField的使用方法詳解
這篇文章主要介紹了java中@JsonFormat和@JSONField使用的相關(guān)資料,@JsonFormat和@JSONField都是用于處理日期格式化的注解,但分別屬于不同的庫和框架,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-12-12