今回はSpring Bootを使って開発している中で、よく見かける@Autowiredアノテーションについて学んだ内容をまとめてみました。最初は「なんとなく付けておけば動くやつ」くらいの理解だったのですが、仕組みをちゃんと理解するとSpringの便利さがぐっとわかりました。
@Autowiredとは?
@AutowiredはSpring Frameworkが持つ**依存性注入(Dependency Injection)**という仕組みのためのアノテーションです。
簡単に言うと、「必要なオブジェクトを自動で用意して渡してくれる」ものです。
たとえば、あるクラスで他のクラスの機能を使いたいとき、普通なら自分でnewしてインスタンスを作りますよね。
UserService userService = new UserService();
でもSpringでは、@Autowiredを使うと、Springがコンテナの中で管理しているUserServiceのインスタンスを自動で注入してくれます。
@Autowired
private UserService userService;
これだけで、UserServiceが使えるようになります。
「自分でnewしなくてもいい」のがポイントです。
どうしてこれが便利なのか?
最初は「newすればいいじゃん」と思っていましたが、実際に使ってみるとメリットが大きいです。
- テストがしやすくなる(モックを差し替えられる)
- 依存関係が明確になる
- クラスの再利用性が高まる
たとえば、UserServiceの中で他のクラスをnewしてしまうと、そのクラスに依存してしまい、差し替えができません。でも@Autowiredで注入すれば、別の実装クラスに切り替えるのも簡単です。
コンストラクタ注入とフィールド注入の違い
最初に@Autowiredを見たとき、フィールドに直接書く方法しか知りませんでした。でも最近のSpringではコンストラクタ注入が推奨されているようです。
@Service
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
このように書くと、テスト時にモックを渡しやすくなったり、依存関係が明確になります。
さらにSpring Boot 2.6以降では、クラスが1つのコンストラクタしか持たない場合、@Autowiredを明示的に書かなくても自動で注入されるようです。
よくあるエラーと対処法
学習中に遭遇したのがこのエラーです。
Field userRepository in UserService required a bean of type 'UserRepository' that could not be found.
これは、SpringがUserRepositoryのBeanを見つけられなかったという意味でした。
原因は、@Repositoryアノテーションを付け忘れていたことでした。
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
アノテーションを付けることで、Springが自動的にBeanとして管理してくれます。
使ってみた感想
最初はただの「おまじない」みたいに思っていた@Autowiredですが、仕組みを理解するとSpringの設計思想が見えてきます。
特に「クラス間の依存をSpringに任せる」という発想は、規模が大きくなるプロジェクトほどありがたいなと感じました。
次は@Componentや@Configurationなど、SpringがどうやってBeanを管理しているのかも掘り下げていきたいです。