はじめに
Spring Boot を使っていると、
@Autowired をほぼ必ず目にします。
「どうやって依存が注入されているの?」
「なぜ new しなくても使えるの?」
「Bean が見つからないときはどうなるの?」
こういった疑問は、
DI(依存性注入)を理解するうえでとても大切です。
この記事では、@Autowired の仕組みを
やさしく・実務で役立つ形 で整理していきます。
まずは基本のコードから見ていきましょう。
まずはコードを確認
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User find(Long id) {
return userRepository.findById(id).orElseThrow();
}
}このように、
new していないのに userRepository が使える
というのが @Autowired の魔法です。
@Autowired の仕組みを一言でいうと…
「Spring が IoC コンテナから Bean を探して、自動で注入してくれる仕組み」
です。
- 自分で new しない
- Spring が管理している Bean を使う
- 型に合うものを自動で見つけてくれる
これが DI(依存性注入)の基本です。
仕組みをもう少し深く理解する
Spring が Bean を作る
まず、@Component / @Service / @Repository / @Configuration などが付いたクラスは Spring の IoC コンテナに登録されます。
@Autowired を見つける
Spring は起動時にクラスをスキャンし、
@Autowired が付いているフィールド・コンストラクタ・メソッドを探します。
型に合う Bean を探す
@Autowired の型(UserRepository)に一致する Bean を IoC コンテナから探します。
見つかった Bean を注入する
一致する Bean が 1 つなら、そのまま注入されます。
@Autowired の注入方法(3 種類)
フィールドインジェクション
@Autowired
private UserRepository userRepository;最も簡単ですが、テストしにくいため実務ではあまり推奨されません。
セッターインジェクション
private UserRepository userRepository;
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}柔軟ですが、必須依存には向きません。
コンストラクタインジェクション(推奨)
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}Spring Boot では
コンストラクタが 1 つなら @Autowired を省略できます。
実務ではこれが最も推奨されます。
@Autowired がうまく動かないときの原因
Bean が登録されていない
@Service / @Component の付け忘れ。
パッケージが ComponentScan の範囲外
Application クラスより上の階層に置いてしまうパターン。
実装クラスが複数ある
@Service
class AService implements UserService {}
@Service
class BService implements UserService {}→ どちらを注入すべきかわからない。
対策
@Autowired
@Qualifier("aService")
private UserService userService;循環参照
A → B → A のように依存がループしていると注入できません。
@Autowired と @Qualifier の関係
@Autowired は「型」で探す
@Autowired
private UserService userService;@Qualifier は「名前」で指定する
@Autowired
@Qualifier("specialUserService")
private UserService userService;Bean が複数あるときに使います。
@Autowired と @Primary の関係
デフォルトの Bean を指定したいとき
@Primary
@Service
public class DefaultUserService implements UserService { ... }複数実装があっても、@Primary が優先されます。
@Autowired と @Lazy の関係
遅延ロードしたいとき
@Autowired
@Lazy
private HeavyService heavyService;起動時ではなく、初めて使うタイミングで生成されます。
あわせて知っておきたいポイント
@Autowired はコンストラクタが 1 つなら省略できる
Spring Boot の便利機能です。
Lombok の @RequiredArgsConstructor と相性抜群
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
}@Autowired は「依存を外から渡す」ための仕組み
new しないことでテストしやすくなります。
使うときに気をつけたいこと
フィールドインジェクションは避ける
テストしにくく、循環参照にも気づきにくいです。
コンストラクタインジェクションを基本にする
最も安全で、Spring 公式も推奨しています。
Bean が複数あるときは @Qualifier / @Primary
曖昧な状態を避けるとトラブルが減ります。
まとめ
@Autowired は、
「Spring が IoC コンテナから Bean を探して注入する仕組み」
です。
- Bean は @Component / @Service などで登録
- @Autowired は型で Bean を探す
- コンストラクタインジェクションが推奨
- 複数 Bean があるときは @Qualifier / @Primary
- パッケージ構成やアノテーションの付け忘れに注意
難しく聞こえますが、
「Spring が new の代わりに依存を渡してくれる」
と理解できれば十分です。

@Autowired の仕組みを理解すると、
DI の世界が一気にクリアになります。
Bean のつながりが見えるようになると、
Spring のコードがぐっと読みやすくなります。
あなたの開発が、今日より少しだけ楽になりますように。

new しなくても仲間が来てくれるなんて…Spring さん、やさしいね。

コメント