はてな
- 「Springで@Autowiredを使うと、nullが出て困っている」
- 「ちゃんと@Autowired対象クラスには@Componentをつけているのになぜ…」
この記事は上記のような疑問を解決します。
@Autowiredがnullになる問題の対処法
理由は単純でした。
- 原因︰@Autowiredを記述しているクラスがnewで作成されていた
- 解決︰newしないようにする
@Autowiredされるクラスの方はしっかり@Componentや@Serviceをつけていましたが、@Autowiredを記述しているクラスの方はnewされていたのですね。
newで生成されたインスタンスはSpringの管理対象ではなくなるので、@Autowiredなど便利なアノテーションが効かなくなります。
具体的に言うと、以下の状態で@Autowiredしてもnullになります。
Testクラスはnewで生成されているので、Springの管理対象外ではなくなり、結果その中で@Autowiredしても失敗して値がnullになるわけですね。
public class Main { Test test = new Test; test.hoge(); //内部でエラー } public class Test { @Autowired private Onigiri onigiri; // onigiriを@Autowired // ただしTestクラスはnewされて作られた // つまりSpringの管理対象外のクラスから外れているクラス // そんなクラスからは@Autowiredアノテーションを使えない // onigiriはnullになる public void hoge() { int price = onigiri.getPrice(); // NullPointerException } } pubilc class Onigiri { private int price = 108; public getPrice() { return this.price; } }
対策
@Autowiredを呼び出しているクラスを、Spring管理対象下に置けば解決します。
つまり、newせずに@Componentや@Serviceを付け@Autowiredすれば良いんですね。
今回の例でいうと、
public class Main{ @Autowired private Test test; // 変更点:Testクラスのnewをやめた test.hoge(); // 成功 } @Component //変更点:@Componentなどの適切なアノテーションを追加 public class Test{ @autowired private Onigiri onigiri; ... }
まとめ
Springで@Autowiredしたらnullになってしまう問題の対処法をご紹介しました。
Newを使ってしまうとSpringの管理対象から外れ、@Autowiredが失敗して値がnullになってしまいます。これを解決するには、newしないようにします。
最後までお読みいただきありがとうございました。