@AutoConfigurationPackage 和 @ComponentScan 有何區別?
來源:江南一點雨
面試真是越來越捲了,最近又有小夥伴在微信上問到松哥這樣一個面試題,想到這兩個的區別其實還有點意思,因為整一篇文章和小夥伴們捋一捋。
首先,從名字上看,這兩個註解意義特別接近,@AutoConfigurationPackage
就是自動配置包,自動配置包的目的是能讓系統掃描到包內的 Bean;@ComponentScan
則是元件掃描,這個松哥在之前的教程中也多次提到過了,就不再贅述了,所以這裡就有一個問題,這兩個註解有啥區別?
首先大家思考這樣一個問題:
現在大多數專案可能都是用的 MyBatis 或者 MyBatis-Plus 這樣的資料持久化框架,當我們在 Spring Boot 中使用 MyBatis 的時候,我們一般需要在 Mapper 介面上新增一個 @Mapper 註解,類似下面這樣:
@Mapper
public interface UserMapper {
}
或者在啟動類上加 Mapper 掃描註解去統一掃描所有的 Mapper 介面,類似下面這樣:
@SpringBootApplication
@MapperScan(basePackages = "org.javaboy.auto_package")
public class AutoPackageApplication {
public static void main(String[] args) {
SpringApplication.run(AutoPackageApplication.class, args);
}
}
平時我們都這樣寫,沒有任何問題,現在假設我們換一個寫法,假如我的類結構如下:
├── main
│ ├── java
│ │ └── org
│ │ └── javaboy
│ │ └── auto_package
│ │ ├── config
│ │ │ ├── AutoPackageApplication.java
│ │ │ └── UserController.java
│ │ ├── mapper
│ │ │ └── UserMapper.java
│ │ └── service
│ │ └── UserService.java
小夥伴們看到,我把啟動類和 UserController 放在一個單獨的包中,UserMapper 和 UserService 也分別位於不同的包中,其中在 UserController 中注入了 UserService,在 UserService 中則注入了 UserMapper,大致上就這麼一個關係。
按照我們之前對 Spring Boot 的理解,這個專案啟動肯定會報錯,因為預設情況下,系統掃描的 Bean 是啟動類所在的包以及子包下的所有 Bean(因為 @SpringBootApplication
註解在啟動類上),所以上面這個專案啟動的時候,能掃描到 UserController,但是掃描不到 UserService,所以啟動的時候會報錯,如下:
大家看下,這意思很明確,UserService 找不到,所以啟動失敗。
解決這個問題的辦法很簡單,要麼將啟動類放到根包下面,這樣所有的 Bean 預設就都能掃描到了,要麼我們重新配置包掃描,這裡我採用第二種方案,我們在啟動類上加 @ComponentScan
註解,重新指定掃描的包,如下:
@SpringBootApplication
@ComponentScan(basePackages = "org.javaboy.auto_package")
public class AutoPackageApplication {
public static void main(String[] args) {
SpringApplication.run(AutoPackageApplication.class, args);
}
}
加上之後,我們再次啟動,發現又報錯了,如下:
雖然再次出錯,但是跟之前的錯誤並不一樣,這次是沒找到 UserMapper 這個 Bean,說明 UserService 是找到了!
從這裡我們就可以看出來,@ComponentScan
註解掃描元件是不會掃描到 @Mapper 註解的!
事實上,@ComponentScan
註解主要是掃描 Spring 家族的各種 Bean,如 @Controller、@Service、@Component、@Repository 以及由此衍生出來的一些其他的 Bean,對於 Spring 家族之外的 Bean,如 MyBatis 的 @Mapper、@MapperScan,JPA 的 @Entity 等,@ComponentScan
都掃不到!
誰能掃到呢?那就是我們今天的另外一個主角 @AutoConfigurationPackage
,這個註解其實就是專門用來掃這些第三方的各種 Bean 的。
現在,我們在專案啟動上加上 @AutoConfigurationPackage
註解,並設定需要掃描的位置,如下:
@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);
}
}
此時,專案就可以成功啟動了,因為 @AutoConfigurationPackage(basePackages = "org.javaboy.auto_package")
註解可以掃描到 @Mapper 註解。
當然,這裡只是為了給大家演示問題,實際場景下直接在啟動類上加
@MapperScan(basePackages = "org.javaboy.auto_package")
註解就可以了。因為 @MapperScan 註解是 mybatis-spring 提供的,而 @Mapper 是 MyBatis 自己提供的,兩個註解的出處本身就不同。
預設情況下,Spring Boot 專案的啟動註解中,實際上已經包含了 @AutoConfigurationPackage
註解,具體位置在 @SpringBootApplication
->@EnableAutoConfiguration
->@AutoConfigurationPackage
,預設該註解沒有指定 basePackages 屬性,表示使用啟動類所在的包作為根包,掃描該包下的所有第三方 Bean,所以我們平時在 Spring Boot 中使用 MyBatis 的時候,是不需要額外加 @AutoConfigurationPackage
註解的。
經過上面問題的演示,相信小夥伴們已經搞明白了 @AutoConfigurationPackage
和 @ComponentScan
的區別了吧?
小結
總結一下:
兩者都是用來掃描 Bean 的。 @ComponentScan
主要用來掃描和 Spring 容器相關的 Bean。@AutoConfigurationPackage
主要用來掃描第三方的 Bean。
僅此而已。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024922/viewspace-2953012/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- laravel/laravel和laravel/framework有何區別?LaravelFramework
- EMR和ERP有何區別(轉)
- 超外差和超再生模組有何區別?
- 住宅IP和資料中心IP有何區別?
- 在Linux中,Jail和Chroot有何區別?LinuxAI
- 伺服器和虛擬主機有何區別伺服器
- DOM 精通了?請問 Node 和 Element 有何區別?
- DOM 精通了?請問 Node 和 Elment 有何區別?
- ConcurrentHashMap和oscache等物件快取有何區別HashMap物件快取
- TDengine 3.0 的 Update 有何區別?
- 伺服器領域,Linux和Windows有何區別?伺服器LinuxWindows
- Python和Matlab有何區別?哪個更難?PythonMatlab
- Tomcat、Nginx和Apache有何區別?Linux如何學?TomcatNginxApacheLinux
- Linux中fork和exec是什麼?有何區別?Linux
- 繞線電感和疊層電感有何區別
- 在Linux中,Linux核心和Shell有何區別?Linux
- 在K8S中,Deployment和Statefulset有何區別?K8S
- SQL JOIN 中 on 與 where 有何區別SQL
- 在資料科學方面,python和R有何區別?資料科學Python
- HTML 裡 img 元素的 src 和 srcset 屬性有何區別?HTML
- 雲原生和雲端計算是什麼?兩者有何區別?
- 驍龍710和驍龍845區別對比 高通驍龍710和845有何區別
- 什麼是OA,與Office 有何區別
- startup mount與startup restrict mount有何區別REST
- Python32位和64位有何區別?如何檢視?Python
- 雲伺服器和傳統伺服器相比有何區別伺服器
- 什麼是滲透測試和安全測試,有何區別?
- DNS欺騙和ARP欺騙是什麼?有何區別?DNS
- 區塊鏈代表的資料庫和傳統資料庫有何區別區塊鏈資料庫
- 不同型別的工業閘道器有何區別?型別
- ERP系統與CRM系統有何區別?進行整合有何作用?
- 小程式電商與傳統電商有何區別?
- SAS介面與SCSI介面的硬碟有何區別硬碟
- 物聯網閘道器中MQTT和Modbus之間有何區別MQQT
- http和https有何區別?恆訊科技總結這11點HTTP
- PyChram社群版和商用版有何區別?這幾點很關鍵!
- 什麼是內網滲透和外網滲透?有何區別?內網
- Jtti:伺服器與資料庫有何區別和聯絡?Jtti伺服器資料庫