最近、Spring フレームワークと Hibernate フレームワークを統合するときに一連の例外が発生しました。今回は主に Spring フレームワークで考えられる例外と解決策について説明します。
sping の強力な Bean コンテナ管理メカニズムを使用して、BeanFactory を通じて javabean のライフサイクル管理を簡単に実装します。ただし、構成管理中に必ずいくつかの例外が発生します。
例外 1: […] タイプの適格な Bean が見つかりません。依存関係の場合
たとえば、BeanB は BeanA に自動的に挿入されます
@Component
public class BeanA {
@Autowired
private BeanB dependency;
…
}
この時点で BeanB が sping の Cntextl で定義されていない場合、起動時に例外がスローされます: そのような Bean 定義例外はありません:
org.springframework.beans.factory.NoSuchBeanDefinitionException:
依存関係に対してタイプ [org.baeldung.packageB.BeanB] の適格な Bean が見つかりません:
少なくとも期待されていますこの依存関係のオートワイヤ候補として適格な 1 つの Bean。
依存関係アノテーション: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
問題の理由は単純で、適格な Bean が少なくとも 1 つ必要であるということです。この依存関係のオートワイヤー候補として。 依存関係注入用に定義された Bean が少なくとも 1 つ必要です。もちろん、アノテーションの使用時およびアノテーション スキャンの設定時にパッケージ スキャンのパスを設定しなかったことが考えられるもう 1 つの理由です。それ以外の場合は Bean が定義されるべきではありません。
例外 2: タイプ […] の適格な Bean が定義されていません
この例外は、タイプの適格な Bean が存在しないことを意味します。その理由は、一意の Bean ではなく、2 つ以上の同一の Bean が定義されているためです。インターフェース IBeanB があり、その 2 つの実装クラス Bean1 と Bean2 があります
@Component
public class BeanB1 は IBeanB {
//
}を実装します
@Component
public class BeanB2 は IBeanB {
//
}を実装します
BeanA が挿入される場合現時点では、インターフェース IBeanB を使用する場合、Spring は
@Component
public class BeanA {
@Autowired
private IBeanB dependency;
…
}
を注入するためにどの実装クラスを使用するべきかを知りません。この時点で、BeanFactory は例外 NoSuchBeanDefinitionException をスローします
原因: org.springframework.beans.factory.NoUniqueBeanDefinitionException:
タイプ [org.baeldung.packageB.IBeanB] の適格な Bean が定義されていません:
単一の一致する Bean が予期されましたが、2 つ見つかりました: beanB1、beanB2
例外から、単一の一致するBeanが期待されましたが、2"が見つかりました。唯一のBeanが見つからなかったことがわかります。
その後、次のメソッドで解決できます
@Component
public class BeanA {
@Autowired
@ Qualifier("beanB2")
private IBeanB dependency;
…
}
sping は、どの Bean がインジェクションのオブジェクトとして使用されているかを明確に認識します
例外 3: […] という名前の Bean が定義されていません
この例外が発生した場合。 、名前で Bean を見つけるために Sping コンテキストに移動すると、例外 NoSuchBeanDefinitionException が発生する可能性があります
@Component
public class BeanAimplements InitializingBean {
@Autowired
private ApplicationContext context;
@Override
public void afterPropertiesSet() {
context.getBean("someBeanName");
}
}
ここで検索すると、someBeanName という名前の定義がないため、例外が発生します
原因: org.springframework.beans.factory.NoSuchBeanDefinitionException:
「 」という名前の Bean がありませんsomeBeanName' が定義されています
この名前の Bean 定義が存在しないことが明確に指摘されています。
例外 4: プロキシ Beans
Bean が Spring コンテキストで JDK 動的プロキシ メカニズムを使用する場合、Bean が挿入されると、プロキシ クラスはターゲット オブジェクトを継承しませんが、同じインターフェイスを実装します。インターフェース を使用する場合は問題ありませんが、実装クラスが挿入される場合、プロキシ クラスはターゲット クラスを継承しないため、現時点では Sping コンテナは Bean を見つけることができません。 Bean がプロキシされる非常に一般的なシナリオは、Spring のトランザクション サポート機能を使用することです。 @Transactional アノテーションを使用してトランザクションを示すか、設定ファイルで設定できます。
たとえば、ServiceA が ServiceB を挿入し、両方のサービスが同時にトランザクションで構成されている場合、クラス挿入を通じて問題が発生します。
@Service
@Transactional
public class ServiceAimplements IServiceA{
@Autowired
private ServiceB serviceB;
…
}
@Service
@Transactional
public class ServiceBimplement IServiceB{
…
}
これと同じインターフェイス インジェクションが使用されている場合、両方のサービスは正常に実行されます。
@Service
@Transactional
public class ServiceA は IServiceA を実装します{
@Autowired
private IServiceB serviceB;
…
}
@Service
@Transactional
public class ServiceB は IServiceB を実装します{
…
}