SpringFrameworkのAutowiredでQualifierタグを利用
こんにちは、かねこです。
はじめに
SpringFrameworkのAutowiredアノテーションを利用することで、クラスを自動インジェクションすることができるようになります。
例
public class SampleService{ @Autowired private Parent parent; }
setter(またはコンストラクタ)を記述する必要がないため、古いSpringFrameworkと比較して、コード量を劇的に減らすことができます。
一方、(めったにありませんが)自動マッピングを使うが故に発生する問題というのもあります。よく遭遇するのは「マッピング対象のクラスが複数ある」ケースです。
動くコードで試してみます。
クラスParent
@Component public class Parent{}
Parentを継承したクラスChild
@Component public class Child extends Parent()
クラスを利用する。
public class SampleService{ @Autowired private Parent parent; }
コンテナ起動で例外
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ’sampleService': Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.Parent com.example.service.SampleServiceImpl.parent; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.example.Parent] is defined: expected single matching bean but found 2: [parent, child]
これは、DIコンテナがオブジェクト設定する時に、型で一致させにいくため、複数マッチしてしまうのが原因です。
解決策
@Qualifierタグを利用することで、bean名でInjectionできるようになります。
public class SampleService{ @Autowired @Qualifier("Parent") private Parent parent; }
かねこでした。