1. 概要

このクイックチュートリアルでは、Springの UnsatisfiedDependencyException 、その原因と回避方法について説明します。

2. UnsatisfiedDependencyExceptionの原因

UnsatisfiedDependencyException は、名前が示すように、一部のBeanまたはプロパティの依存関係が満たされない場合にスローされます。

これは、Springアプリケーションがbeanを配線しようとして、必須の依存関係の1つを解決できない場合に発生する可能性があります。

3. アプリケーション例

InventoryRepositoryに依存するサービスクラスPurchaseDeptServiceがあるとします。

@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. コンポーネント注釈がありません

次に、@RepositoryアノテーションをShoeRepositoryクラスから削除しましょう。

public class ShoeRepository implements InventoryRepository {
}

アプリケーションを再度起動すると、次のエラーメッセージが表示されます。 UnsatisfiedDependencyException:「purchaseDeptService」という名前のBeanの作成中にエラーが発生しました:コンストラクターパラメーター0で表現された不満足な依存関係

Springは、 ShoesRepository beanをワイヤリングしてアプリケーションコンテキストに追加するように指示されていなかったため、注入できず、例外をスローしました。

@RepositoryアノテーションをShoeRepositoryに追加すると、問題が解決します。

5. パッケージがスキャンされていません

次に、 ShoesRepository 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 が発生する最も一般的なケースをいくつか見てから、これらの問題を解決する方法を学びました。

SpringBeanCreationExceptionに関するより一般的なチュートリアルもあります。

ここに示されているコードは、GitHubにあります。