Springの@Autowiredが失敗した時のチェックポイント
前書き
チェックリストは以下の通り。 上から順にチェックすると良いです。
なお、本文書は SpringBoot 1.2 ~ 1.4 の頃に書かれたものです。2.x になると少し事情が変わるかもしれません。
(2019/04/09 あまりにもそっけない文書だったので肉付け&改訂)
static 変数
@Autowired
したいフィールドが static の場合、インジェクションされません。
static を外しましょう。
@Component
の付け忘れ
@Autowired
したいクラスに、 @Component
がついていないと部品として認識されません。
ついてなければつけてみましょう。
ただし、これで直らなかった場合は別のアノテーションが @Component
相当の認識をされている
可能性が高いので元に戻しておきましょう。(害がない場合が多いと思いますが)
例えば、 @Service
@Repository
が既についているのであれば、部品として認識されるはずなので
@Component
をつけても解決しません。
@Component
されたクラスが @ComponentScan
の範囲外
@SpringBootApplication
がついたクラスのパッケージとその配下のパッケージは自動的にスキャンされます。
しかし、それ以外のパッケージに存在するクラスは部品探索範囲外なので、部品として認識されません。
解決方法としては、
- 問題のクラスを、
@SpringBootApplication
のパッケージ(配下含む)に移動する -
@SpringBootApplication
のついたクラスに、@ComponentScan("パッケージ")
を追加する
@Autowired
したいクラスは、 @Component
ではない
@Component
ではないクラスは Spring の管轄外なので @Autowired
は効きません。
@Component
されたクラスの名前が他と重複している
Springboot 等の依存ライブラリ内の部品と名前が重複している場合、無視される場合があります。
試しにクラス名を変えると上手くいくかもしれません。(正確には無視というより優先順位問題)
特に一般的な名前をクラスにつけたクラスのみが当てはまる場合、試してみる価値はあります。
ダメだった名前の例) Environment
ご参考情報
@ComponentScan
の書き方例
@ComponentScan(“org.example.somepackage”)
@SpringBootApplication
public class SpringBootApplication implements CommandLineRunner {
// (略)
// この書き方は古いかもしれない
@ComponentScan(basePackages = {"com.example.pkg1","com.example.pkg2"})
Discussion