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 の書き方例

<code class="language-java">@ComponentScan(“org.example.somepackage”)
@SpringBootApplication
public class SpringBootApplication implements CommandLineRunner {
// (略)
`// この書き方は古いかもしれない
@ComponentScan(basePackages = {"com.example.pkg1","com.example.pkg2"})