SpringBoot的ComponentScan原理
本問將幫助您瞭解Spring中最重要的概念 - 元件掃描。Spring Boot在元件掃描方面做了一些魔術
@ComponentScan
如果你瞭解元件掃描,你就會理解Spring。Spring是一個依賴注入框架。它完全是關於依賴的bean和wiring。
定義Spring Beans的第一步是新增正確的註釋 - @Component或@Service或@Repository。但是,Spring不知道bean在哪個包下面,除非你告訴它去哪裡搜尋包。
這部分“告訴Spring到哪裡搜尋”稱為元件掃描。
你必須定義了需要掃描的包,為包定義元件掃描後,Spring將搜尋包及其所有子包以獲取元件/ bean。
下面展示瞭如何進行元件掃描的定義:
Spring Boot專案中的元件掃描
- 如果你的其他包層次結構位於使用@SpringBootApplication標註主應用程式下方,則隱式元件掃描將自動涵蓋。也就是說,不要明確標註@ComponentScan,Spring Boot會自動搜尋當前應用主入口目錄及其下方子目錄。
- 如果其他包中的bean /元件不在當前主包路徑下面,,則應手動使用@ComponentScan 新增
- 如果使用了@ComponentScan ,那麼Spring Boot就全部依賴你的定義,如果定義出錯,會出現autowired時出錯,報a bean of type that could not be found錯誤,讓你很惱火哦。
#######詳細示例
考慮下面:
package com.jdon.springboot @SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } }
@SpringBootApplication定義在MyApplication這個類上面,而這個類在包com.jdon.springboot下面。
@SpringBootApplication定義了對包com.jdon.springboot進行自動元件掃描。
如果所有元件都在上述包或其子包中定義,則一切正常。
但是,假設其中一個元件是在包中定義的 com.jdon.springboot2下,在這種情況下,需要將新包新增到元件掃描中。
兩個選項
-
定義@ComponentScan(“com.jdon.springboot2”)
- 這將掃描com.jdon.springboot2的整個父樹。
-
或者使用陣列定義兩個特定的元件掃描。
- @ComponentScan({“com.jdon.springboot2.abc”,”com.jdon.springboot2.efg”})
與元件掃描相關的錯誤
#### No qualifying bean of type found
No qualifying bean of type [com.jdon.springboot.jpa.UserRepository] found for dependency [com.jdon.springboot.jpa.UserRepository]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
或在Intellij Idea中顯示 incorrectly saying no beans of type found for autowired repository
```
上述兩個問題的根本原因相同 - 元件未被Spring boot發現。
你需要檢查三種可能的情況。尚未新增正確的註釋 - @ Controller,@ Repository或@Controller ;尚未新增元件掃描;元件包中未定義所需要的元件包名。
有兩個解決選項:1)添加註釋或元件掃描2)將元件移動到已在元件掃描下的包中
@Component和@ComponentScan有什麼區別?
@Component和@ComponentScan用於不同目的。
- @Component表示一個類可能是建立bean的候選者。就像舉手一樣。
- @ComponentScan正在搜尋元件包。試圖找出誰都舉起手來。