1. 概述
在本快速教程中,我們將解釋 Spring 的 UnsatisfiedDependencyException,它是什麼原因引起的以及如何避免它。
2. 導致UnsatisfiedDependencyException 的原因
UnsatisfiedDependencyException 當名稱所示,某些 Bean 或屬性依賴項未被滿足時會拋出。
這可能發生在 Spring 應用程序嘗試注入 Bean 時,無法解析其中一個強制依賴項時。
3. 示例應用程序
假設我們有一個服務類 PurchaseDeptService,它依賴於 InventoryRepository:
@Service
public class PurchaseDeptService {
public PurchaseDeptService(InventoryRepository repository) {
this.repository = repository;
}
}public interface InventoryRepository {
}
@Repository
public class ShoeRepository implements InventoryRepository {
}@SpringBootApplication
public class SpringDependenciesExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringDependenciesExampleApplication.class, args);
}
}
目前,我們假設所有這些類都位於同一個名為 com.baeldung.dependency.exception.app 的包中。
當我們運行此 Spring Boot 應用程序時,一切正常。
讓我們看看如果我們省略配置步驟可能會遇到什麼問題。
4. 組件註解缺失
現在,讓我們從我們的 ShoeRepository 類中移除 @Repository 註解:
public class ShoeRepository implements InventoryRepository {
}當我們重新啓動應用程序時,我們會看到以下錯誤消息: 找不到依賴項異常:創建名為 ‘purchaseDeptService’ 的 Bean 失敗:依賴項未滿足,通過構造參數 0 表達
Spring 沒有被指示將 ShoeRepository Bean 注入並添加到應用程序上下文中,因此無法注入它並拋出異常。
添加 @Repository 註解到 ShoeRepository 中可以解決問題。
5. 包未掃描
現在,我們將 ShoeRepository(以及 InventoryRepository)放入一個名為 com.baeldung.dependency.exception.repository 的單獨包中。
再次運行我們的應用程序,它仍然會拋出 UnsatisfiedDependencyException。
為了解決這個問題,我們可以配置父包的包掃描,並確保所有相關的類都包含在其中:
@SpringBootApplication
@ComponentScan(basePackages = {"com.baeldung.dependency.exception"})
public class SpringDependenciesExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringDependenciesExampleApplication.class, args);
}
}
6. 非唯一依賴解析
假設我們添加另一個 InventoryRepository 實現——DressRepository:
@Repository
public class DressRepository implements InventoryRepository {
}
現在當我們運行我們的應用程序時,它會再次拋出 UnsatisfiedDependencyException
但是,這次的情況有所不同。事實上,當存在多個滿足該依賴項的 Bean 時,依賴項無法被解析。
為了解決這個問題,我們可能需要為倉庫添加 @Qualifier,以區分它們。
@Qualifier("dresses")
@Repository
public class DressRepository implements InventoryRepository {
}
@Qualifier("shoes")
@Repository
public class ShoeRepository implements InventoryRepository {
}此外,我們需要為 PurchaseDeptService 構造函數的依賴項添加一個限定符:
public PurchaseDeptService(@Qualifier("dresses") InventoryRepository repository) {
this.repository = repository;
}這將使 DressRepository 成為唯一可行的選項,Spring 將將其注入到 PurchaseDeptService 中。
7. 結論
在本文中,我們探討了多種常見的 UnsatisfiedDependencyException 出現情況,並學習瞭如何解決這些問題。
我們還提供了一篇更通用的 Spring BeanCreationException 教程。