春の満たされていない依存関係
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.example.dependency.exception.appという名前の同じパッケージにあると想定します。
このSpring Bootアプリケーションを実行すると、すべてが正常に機能します。 構成手順をスキップした場合に発生する可能性のある問題の種類を見てみましょう。
4. コンポーネント注釈がありません
それでは、ShoeRepositoryクラスから@Repository annotationを削除しましょう。
public class ShoeRepository implements InventoryRepository {
}
アプリケーションを再起動すると、次のエラーメッセージが表示されます:UnsatisfiedDependencyException: Error creating bean with name ‘purchaseDeptService': Unsatisfied dependency expressed through constructor parameter 0
Springは、ShoeRepository Beanをワイヤリングしてアプリケーションコンテキストに追加するように指示されていなかったため、注入できず、例外をスローしました。
@RepositoryアノテーションをShoeRepositoryに戻すと、問題が解決します。
5. パッケージがスキャンされていません
ここで、ShoeRepositoryを(InventoryRepositoryとともに)com.example.dependency.exception.repository.という名前の別のパッケージに入れましょう。
繰り返しになりますが、アプリを実行すると、UnsatisfiedDependencyExceptionがスローされます。 これを解決するには、親パッケージでパッケージスキャンを構成し、関連するすべてのクラスが含まれていることを確認します。
@SpringBootApplication
@ComponentScan(basePackages = {"com.example.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.がスローされます。
ただし、今回は状況が異なります。 たまたま、dependency cannot be resolved when there’s more than one bean that satisfies it。
これを解決するには、リポジトリを区別するために@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に関するより一般的なチュートリアルも参照してください。
ここに示されているコードはover on GitHubにあります。