【Spring Boot】@Autowired が動かない理由をやさしく解説

Java入門・実践
スポンサーリンク
スポンサーリンク

はじめに

Spring を使っていると、
「@Autowired が効かない」「注入されない」「null になる」
という現象に出会うことがあります。

最初は原因がわかりにくく、
「Spring が動いていないのかな…?」と不安になることもあると思います。

この記事では、@Autowired が動かない理由を やさしく・実務で役立つ形 で整理していきます。

まずはコードを見て、そこから少しずつ理解していきましょう。

まずはコードを確認

Java
@Service
public class GreetingService {
    public String greet() {
        return "Hello!";
    }
}

@RestController
public class HelloController {

    @Autowired
    private GreetingService greetingService;

    @GetMapping("/hello")
    public String hello() {
        return greetingService.greet();
    }
}

このコードは一見問題なさそうですが、
状況によっては greetingService が注入されず、null になることがあります。

コードのしくみを解説

@Autowried が動かない理由は、大きく分けて次のようなものがあります。

Bean が登録されていない

@Service@Component が付いていないと、
Spring が Bean として認識できません。

例: アノテーションの付け忘れ

Java
public class GreetingService {  // ← Bean にならない
}

コンポーネントスキャンの範囲外

Spring Boot は、 メインクラスのパッケージ配下だけをスキャン します。

パッケージ構成がずれていると、Bean が見つからず注入されません。

例:
メインクラスが com.example.demo
サービスが com.other.service
→ スキャンされない

型が複数あって特定できない

同じ型の Bean が複数あると、Spring はどれを注入すべきかわからずエラーになります。

例:
GreetingService が 2 つある
→ NoUniqueBeanDefinitionException

new で自分で作っている

DI を使う場合、new でインスタンスを作ると
IoCコンテナの管理外になり、@Autowired が効きません。

例:

Java
GreetingService service = new GreetingService(); // Spring 管理外

フィールド注入のタイミング問題

フィールド注入は便利ですが、
テストや特殊な状況では初期化タイミングがずれて null になることがあります。

実務では コンストラクタ注入 が推奨される理由のひとつです。

@Autowired が付いていない

単純な付け忘れもよくあります。

あわせて知っておきたいポイント

コンストラクタ注入なら @Autowired は省略可能

コンストラクタが 1 つだけなら、Spring が自動で注入してくれます。

Java
@RestController
public class HelloController {

    private final GreetingService greetingService;

    public HelloController(GreetingService greetingService) {
        this.greetingService = greetingService;
    }
}

Bean の名前で注入したい場合

@Qualifier を使うと、特定の Bean を指定できます。

@Repository は例外変換が行われる

Repository 層は特別扱いされるため、
アノテーションの付け忘れは特に注意が必要です。

使うときに気をつけたいこと

パッケージ構成を整える

メインクラスの位置を意識するだけで、
@Autowried が動かない問題の多くが解決します。

コンストラクタ注入を基本にする

テストしやすく、初期化の順番も安定します。

Bean の重複に注意する

同じ型の Bean が複数ある場合は、
@Qualifier や Bean 名の指定が必要です。

まとめ

@Autowired が動かない理由はさまざまですが、
多くは
「Bean が見つからない」
「スキャンされていない」
「複数あって特定できない」
といったシンプルな原因です。

難しく聞こえますが、
「Spring が Bean を見つけられるかどうか」
を意識すると、問題の切り分けがぐっと楽になります。


decopon
decopon

@Autowired が効かないときは焦ってしまいますが、
原因をひとつずつ確認していくと、必ず解決に近づきます。
あなたの開発が、今日より少しだけ楽になりますように。

moco
moco

Bean さんが見つからないと、Spring さんも困っちゃうんだね。かくれんぼみたいでかわいいけどなあ。

コメント

タイトルとURLをコピーしました