@Autowired、@Inject、@Resourceの違いについての検証
Java
spring
この記事は最終更新日から1年以上が経過しています。
@Autowired、@Inject、@Resourceについて、共通的な動きとしては、何れも自動でフィールドにbeanをインジェクションすることです。今回はそれらの違いについて、検証してみます。
@Resource⇨javax.annotation
@Inject⇨javax.inject
@Autowired⇨org.springframework.bean.factory
事前準備
以下のクラスを用意する。
・インタフェースクラスPrint
・インタフェースクラスPrintの実装クラスHelloWorldPrintImp
・インタフェースクラスPrintの実装クラスHelloMoonPrintImp
public interface Print {
public void print();
}
@Component
public class HelloWorldPrintImp implements Print {
@Override
public void print() {
System.out.println("Hello World");
}
}
@Component
public class HelloMoonPrintImp implements Print {
@Override
public void print() {
System.out.println("Hello Moon");
}
}
検証1
@Autowired
private Print print;
@Inject
private Print print;
@Resource
private Print print;
上記のケースは、何れも例外NoUniqueBeanDefinitionExceptionが発生した。
インタフェースクラスPrintの実装クラスのbeanがユニックでないのが原因である。
検証2
@Autowired
private Print helloWorldPrintImp;
@Inject
private Print helloWorldPrintImp;
@Resource
private Print helloWorldPrintImp;
インジェクション対象のフィルド名を@Componentのクラス名と一致すればに、検証1の例外を回避し、上記何れも正常にインジェクションできる。
実行結果は以下の通りです。
@Autowired:Hello World
@Inject:Hello World
@Resource:Hello World
検証3
@Autowired
@Qualifier("helloWorldPrintImp")
private Print print;
@Inject
@Qualifier("helloWorldPrintImp")
private Print print;
@Resource
@Qualifier("helloWorldPrintImp")
private Print print;
@Qualifier("name")を上記のアノテーションと併用することで、インジェクション対象bean名を指定でき、検証1の例外も同様に回避する。
実行結果は以下の通りです。
@Autowired:Hello World
@Inject:Hello World
@Resource:Hello World
検証4
@Autowired
@Qualifier("helloMoonPrintImp")
private Print helloWorldPrintImp;
@Inject
@Qualifier("helloMoonPrintImp")
private Print helloWorldPrintImp;
@Resource
@Qualifier("helloMoonPrintImp")
private Print helloWorldPrintImp;
フィルド名=コンポーネントクラス名、且つ@Qualifierで別のコンポーネントを指定する場合、@Autowiredと@Injectの動きは一緒であり、@Qualifierで指定するコンポーネントがインジェクションされている。
@Resourceは@Qualifierで指定のコンポーネントを無視し、フィルド名と一致のコンポーネントがインジェクションされている。
実行結果は以下の通りです。
@Autowired:Hello Moon
@Inject:Hello Moon
@Resource:Hello World
また、@Resource(name="name")でコンポーネント名を指定できる。
@Resource(name="helloMoonPrintImp")
private Print helloWorldPrintImp;
その場合に、nameで指定されるコンポーネントがインジェクションされる。
実行結果は以下の通りです。
@Resource:Hello Moon
結論
タイプ一致の場合に、インジェクションの優先順位:
@Autowiredと@Inject
1.Qualifier指定のコンポーネント
2.フィルド名と一致のコンポーネント
@Resource
1.@Resource(name="name")で指定のコンポーネント
2.フィルド名と一致のコンポーネント
3.Qualifier指定のコンポーネント
댓글 없음:
댓글 쓰기