javascript
SpringBoot默认包扫描机制及@ComponentScan指定扫描路径详解
SpringBoot默認(rèn)包掃描機(jī)制及@ComponentScan指定掃描路徑詳解
SpringBoot默認(rèn)包掃描機(jī)制
標(biāo)注了@Component和@Component的衍生注解如@Controller,@Service,@Repository就可以把當(dāng)前的Bean加入到IOC容器中。那么SpringBoot是如何知道要去掃描@Component注解的呢。@ComponentScan做的事情就是告訴Spring從哪里找到bean
SpringBoot默認(rèn)包掃描機(jī)制: 從啟動(dòng)類所在包開始,掃描當(dāng)前包及其子級(jí)包下的所有文件。我們可以通過(guò)以下的測(cè)試來(lái)驗(yàn)證一下。
啟動(dòng)應(yīng)用并訪問(wèn)BannerController這個(gè)控制器,目錄結(jié)構(gòu)如圖
訪問(wèn)結(jié)果正常
當(dāng)把BannerController移動(dòng)到上一級(jí)目錄,應(yīng)用可以正常啟動(dòng)
但是再次訪問(wèn)剛才的路徑時(shí)卻出現(xiàn)了如下錯(cuò)誤,代碼是沒(méi)有變動(dòng)的,是Controller掃描 不到了。
實(shí)際上SpringBoot是通過(guò)@ComponentScan進(jìn)行掃描。默認(rèn)情況下,入口類上面的@SpringBootApplication里面有一個(gè)@ComponentScan,也就相當(dāng)于@ComponentScan標(biāo)注在入口類上。
所以默認(rèn)情況下,掃描入口類同級(jí)及其子級(jí)包下的所有文件。當(dāng)我們想自己制定包掃描路徑就需要加一個(gè)@ComponentScan
@ComponentScan的使用
常用參數(shù)含義
- basePackages與value: 用于指定包的路徑,進(jìn)行掃描(默認(rèn)參數(shù))
- basePackageClasses: 用于指定某個(gè)類的包的路徑進(jìn)行掃描
- includeFilters: 包含的過(guò)濾條件
- FilterType.ANNOTATION:按照注解過(guò)濾
- FilterType.ASSIGNABLE_TYPE:按照給定的類型
- FilterType.ASPECTJ:使用ASPECTJ表達(dá)式
- FilterType.REGEX:正則
- FilterType.CUSTOM:自定義規(guī)則
- excludeFilters: 排除的過(guò)濾條件,用法和includeFilters一樣
- nameGenerator: bean的名稱的生成器
- useDefaultFilters: 是否開啟對(duì)@Component,@Repository,@Service,@Controller的類進(jìn)行檢測(cè)
指定要掃描的包
上述例子,如果想掃描啟動(dòng)類上一級(jí)包,使用@ComponentScan指定包掃描路徑,即可將BannerController加入到容器
@SpringBootApplication @ComponentScan("com.lin") public class MissyouApplication {public static void main(String[] args) {SpringApplication.run(MissyouApplication.class, args);} }excludeFilters 排除某些包的掃描
測(cè)試類準(zhǔn)備:
@Controller public class BannerController {BannerController(){System.out.println("Hello BannerController");} } -------------------------------------------------------------------- @Service public class TestService {TestService(){System.out.println("Hello TestService");} }目錄結(jié)構(gòu)如下:
啟動(dòng)類上加@ComponentScan指定掃描lin這個(gè)包并排除@Controller這個(gè)注解標(biāo)注的類
@SpringBootApplication @ComponentScan(value = "com.lin",excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class})}) public class MissyouApplication {public static void main(String[] args) {SpringApplication.run(MissyouApplication.class, args);} }啟動(dòng)應(yīng)用,控制臺(tái)打印出了TestService而沒(méi)有BannerController
@Component與@ComponentScan
在某個(gè)類上使用@Component注解,表明當(dāng)需要?jiǎng)?chuàng)建類時(shí),這個(gè)被注解標(biāo)注的類是一個(gè)候選類。就像是有同學(xué)在舉手。 @ComponentScan 用于掃描指定包下的類。就像看都有哪些舉手了。
springboot多模塊包掃描問(wèn)題的解決方法
問(wèn)題描述:
springboot建立多個(gè)模塊,當(dāng)一個(gè)模塊需要使用另一個(gè)模塊的服務(wù)時(shí),需要注入另一個(gè)模塊的組件,如下面圖中例子:
memberservice模塊中的MemberServiceApiImpl類需要注入common模塊中的RedisService組件,該怎么注入呢?
解決:
在memberservice模塊的啟動(dòng)類上加上RedisService類所在包的全路徑的組件掃描,就像這樣:
注意啟動(dòng)類上方的注解@ComponentScan(basePackages={“com.whu.commom.redis”}),這一句實(shí)際上就已經(jīng)加上了RedisService的組件掃描,但是這樣做是有問(wèn)題的,我發(fā)現(xiàn)啟動(dòng)后服務(wù)不能正常訪問(wèn)。查找資料后發(fā)現(xiàn)是因?yàn)?#64;ComponentScan 和@SpringBootApplication注解的包掃描有沖突,@ComponentScan注解包掃描會(huì)覆蓋掉@SpringBootApplication的包掃描。解決辦法就是在@ComponentScan(basePackages={“com.whu.commom.redis”})的基礎(chǔ)上加上@SpringBootApplication掃描的包,那么@SpringBootApplication掃描了哪些包呢?實(shí)際上,它默認(rèn)掃描的是啟動(dòng)類所在的包及其子包,所以我的例子上需要改成@ComponentScan(basePackages={“com.whu.commom.redis”,“com.whu.memberservice”}). OK ,結(jié)束!!
總結(jié)
以上是生活随笔為你收集整理的SpringBoot默认包扫描机制及@ComponentScan指定扫描路径详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: PyTorch随笔-2
- 下一篇: SpringAOP+自定义注解实现日志功