LoginSignup
109
104

More than 5 years have passed since last update.

@Autowired、@Inject、@Resourceの違いについての検証

Last updated at Posted at 2016-05-13

@Autowired@Inject@Resourceについて、共通的な動きとしては、何れも自動でフィールドにbeanをインジェクションすることです。今回はそれらの違いについて、検証してみます。

  • @Resourcejavax.annotation
  • @Injectjavax.inject
  • @Autowiredorg.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指定のコンポーネント

109
104
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
109
104