@AutoConfigurationPackage與@ComponentScan注解區(qū)別
引言
面試真是越來(lái)越卷了,最近又有小伙伴在微信上問(wèn)到松哥這樣一個(gè)面試題,想到這兩個(gè)的區(qū)別其實(shí)還有點(diǎn)意思,因?yàn)檎黄恼潞托』锇閭冝垡晦邸?/p>
AutoConfigurationPackage 就是自動(dòng)配置包
首先,從名字上看,這兩個(gè)注解意義特別接近,@AutoConfigurationPackage 就是自動(dòng)配置包,自動(dòng)配置包的目的是能讓系統(tǒng)掃描到包內(nèi)的 Bean;@ComponentScan 則是組件掃描,這個(gè)松哥在之前的教程中也多次提到過(guò)了,就不再贅述了,所以這里就有一個(gè)問(wèn)題,這兩個(gè)注解有啥區(qū)別?
首先大家思考這樣一個(gè)問(wèn)題:
現(xiàn)在大多數(shù)項(xiàng)目可能都是用的 MyBatis 或者 MyBatis-Plus 這樣的數(shù)據(jù)持久化框架,當(dāng)我們?cè)?Spring Boot 中使用 MyBatis 的時(shí)候,我們一般需要在 Mapper 接口上添加一個(gè) @Mapper 注解,類(lèi)似下面這樣:
@Mapper
public?interface?UserMapper?{
}
或者在啟動(dòng)類(lèi)上加 Mapper 掃描注解去統(tǒng)一掃描所有的 Mapper 接口,類(lèi)似下面這樣:
@SpringBootApplication
@MapperScan(basePackages?=?"org.javaboy.auto_package")
public?class?AutoPackageApplication?{
????public?static?void?main(String[]?args)?{
????????SpringApplication.run(AutoPackageApplication.class,?args);
????}
}
平時(shí)我們都這樣寫(xiě),沒(méi)有任何問(wèn)題,現(xiàn)在假設(shè)我們換一個(gè)寫(xiě)法,假如我的類(lèi)結(jié)構(gòu)如下:
├── main │?? ├── java │?? │?? └── org │?? │?? └── javaboy │?? │?? └── auto_package │?? │?? ├── config │?? │?? │?? ├── AutoPackageApplication.java │?? │?? │?? └── UserController.java │?? │?? ├── mapper │?? │?? │?? └── UserMapper.java │?? │?? └── service │?? │?? └── UserService.java
小伙伴們看到,我把啟動(dòng)類(lèi)和 UserController 放在一個(gè)單獨(dú)的包中,UserMapper 和 UserService 也分別位于不同的包中,其中在 UserController 中注入了 UserService,在 UserService 中則注入了 UserMapper,大致上就這么一個(gè)關(guān)系。
按照我們之前對(duì) Spring Boot 的理解,這個(gè)項(xiàng)目啟動(dòng)肯定會(huì)報(bào)錯(cuò),因?yàn)槟J(rèn)情況下,系統(tǒng)掃描的 Bean 是啟動(dòng)類(lèi)所在的包以及子包下的所有 Bean(因?yàn)?nbsp;@SpringBootApplication 注解在啟動(dòng)類(lèi)上),所以上面這個(gè)項(xiàng)目啟動(dòng)的時(shí)候,能掃描到 UserController,但是掃描不到 UserService,所以啟動(dòng)的時(shí)候會(huì)報(bào)錯(cuò),如下:

大家看下,這意思很明確,UserService 找不到,所以啟動(dòng)失敗。
在啟動(dòng)類(lèi)上加 @ComponentScan 注解
解決這個(gè)問(wèn)題的辦法很簡(jiǎn)單,要么將啟動(dòng)類(lèi)放到根包下面,這樣所有的 Bean 默認(rèn)就都能掃描到了,要么我們重新配置包掃描,這里我采用第二種方案,我們?cè)趩?dòng)類(lèi)上加 @ComponentScan 注解,重新指定掃描的包,如下:
@SpringBootApplication
@ComponentScan(basePackages?=?"org.javaboy.auto_package")
public?class?AutoPackageApplication?{
????public?static?void?main(String[]?args)?{
????????SpringApplication.run(AutoPackageApplication.class,?args);
????}
}
加上之后,我們?cè)俅螁?dòng),發(fā)現(xiàn)又報(bào)錯(cuò)了,如下:

雖然再次出錯(cuò),但是跟之前的錯(cuò)誤并不一樣,這次是沒(méi)找到 UserMapper 這個(gè) Bean,說(shuō)明 UserService 是找到了!
從這里我們就可以看出來(lái),@ComponentScan 注解掃描組件是不會(huì)掃描到 @Mapper 注解的!
事實(shí)上,@ComponentScan 注解主要是掃描 Spring 家族的各種 Bean,如 @Controller、@Service、@Component、@Repository 以及由此衍生出來(lái)的一些其他的 Bean,對(duì)于 Spring 家族之外的 Bean,如 MyBatis 的 @Mapper、@MapperScan,JPA 的 @Entity 等,@ComponentScan 都掃不到!
誰(shuí)能掃到呢?那就是我們今天的另外一個(gè)主角 @AutoConfigurationPackage,這個(gè)注解其實(shí)就是專(zhuān)門(mén)用來(lái)掃這些第三方的各種 Bean 的。
現(xiàn)在,我們?cè)陧?xiàng)目啟動(dòng)上加上 @AutoConfigurationPackage 注解,并設(shè)置需要掃描的位置,如下:
@SpringBootApplication
@AutoConfigurationPackage(basePackages?=?"org.javaboy.auto_package")
@ComponentScan(basePackages?=?"org.javaboy.auto_package")
public?class?AutoPackageApplication?{
????public?static?void?main(String[]?args)?{
????????SpringApplication.run(AutoPackageApplication.class,?args);
????}
}
此時(shí),項(xiàng)目就可以成功啟動(dòng)了,因?yàn)?nbsp;@AutoConfigurationPackage(basePackages = "org.javaboy.auto_package") 注解可以?huà)呙璧?@Mapper 注解。
當(dāng)然,這里只是為了給大家演示問(wèn)題,實(shí)際場(chǎng)景下直接在啟動(dòng)類(lèi)上加 @MapperScan(basePackages = "org.javaboy.auto_package") 注解就可以了。因?yàn)?@MapperScan 注解是 mybatis-spring 提供的,而 @Mapper 是 MyBatis 自己提供的,兩個(gè)注解的出處本身就不同。
默認(rèn)情況下,Spring Boot 項(xiàng)目的啟動(dòng)注解中,實(shí)際上已經(jīng)包含了 @AutoConfigurationPackage 注解,具體位置在 @SpringBootApplication->@EnableAutoConfiguration->@AutoConfigurationPackage,默認(rèn)該注解沒(méi)有指定 basePackages 屬性,表示使用啟動(dòng)類(lèi)所在的包作為根包,掃描該包下的所有第三方 Bean,所以我們平時(shí)在 Spring Boot 中使用 MyBatis 的時(shí)候,是不需要額外加 @AutoConfigurationPackage 注解的。
經(jīng)過(guò)上面問(wèn)題的演示,相信小伙伴們已經(jīng)搞明白了 @AutoConfigurationPackage 和 @ComponentScan 的區(qū)別了吧?
總結(jié)
兩者都是用來(lái)掃描 Bean 的。
@ComponentScan 主要用來(lái)掃描和 Spring 容器相關(guān)的 Bean。
@AutoConfigurationPackage 主要用來(lái)掃描第三方的 Bean。
以上就是@AutoConfigurationPackage與@ComponentScan注解區(qū)別的詳細(xì)內(nèi)容,更多關(guān)于@AutoConfigurationPackage@ComponentScan區(qū)別的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- 基于@ComponentScan注解及其XML配置方式
- 關(guān)于@ComponentScan注解的用法及作用說(shuō)明
- SpringBoot中@ComponentScan注解過(guò)濾排除不加載某個(gè)類(lèi)的3種方法
- spring?boot自動(dòng)裝配之@ComponentScan注解用法詳解
- Spring @ComponentScan注解使用案例詳細(xì)講解
- Spring @ComponentScan注解掃描組件原理
- Spring?component-scan?XML配置與@ComponentScan注解配置
- 基于ComponentScan注解的掃描范圍及源碼解析
相關(guān)文章
Mybatis-Plus實(shí)現(xiàn)用戶(hù)ID自增出現(xiàn)的問(wèn)題解決
項(xiàng)目基于 SpringBoot + MybatisPlus 3.5.2 使用數(shù)據(jù)庫(kù)自增ID時(shí), 出現(xiàn)重復(fù)鍵的問(wèn)題,本文就來(lái)介紹一下解決方法,感興趣的可以了解一下2023-09-09
mybatis3.4.6 批量更新 foreach 遍歷map 的正確姿勢(shì)詳解
這篇文章主要介紹了mybatis3.4.6 批量更新 foreach 遍歷map 的正確姿勢(shì)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11
Mybatis的collection三層嵌套查詢(xún)方式(驗(yàn)證通過(guò))
這篇文章主要介紹了Mybatis的collection三層嵌套查詢(xún)方式(驗(yàn)證通過(guò)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
logback和log4j日志框架堆棧信息添加TraceId方式
這篇文章主要介紹了logback和log4j日志框架堆棧信息添加TraceId方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
JPA?使用criteria簡(jiǎn)單查詢(xún)工具類(lèi)方式
這篇文章主要介紹了JPA?使用criteria簡(jiǎn)單查詢(xún)工具類(lèi)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
springboot 熱啟動(dòng)的過(guò)程圖解
這篇文章主要介紹了springboot 熱啟動(dòng)的過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
MyBatis實(shí)現(xiàn)動(dòng)態(tài)SQL的實(shí)現(xiàn)方法
詳解spring-data-jpa中jpql的投影查詢(xún)

