[Java] @Autowiredを書かなくてもDIは動く?最新のSpring事情を解説
こんにちは。ゆうせいです。
これは非常に鋭い質問ですね!
「DI(依存性の注入)= @Autowired を書くこと」と覚えている初心者の方はとても多いのですが、実はその認識は 半分正解で、半分間違い なんです。
結論から言うと、@Autowired が書いていなくても、DI はバリバリ使われています。
むしろ最近のSpring開発の現場では、あえて「@Autowired を書かない」スタイルが主流になっているほどです。
どういうことなのか?
「DIを使っているけれど、@Autowiredが見当たらないケース」と、「DIの準備をするためのアノテーション」の2つの視点から、分かりやすく解説しますね。
1. @Autowiredを書かない「暗黙のDI」
以前(少し古いバージョン)のSpringでは、DIをする場所に必ず @Autowired という目印をつける必要がありました。
しかし、Spring 4.3というバージョン以降、ルールが大きく変わりました。
「コンストラクタ(クラスの入口)が1つしかない場合、Springが勝手にDIしてくれる」 ようになったのです。
コードで比較してみましょう。
昔の書き方(@Autowired必須)
@Service
public class Hero {
private final Weapon weapon;
@Autowired // 「ここでDIしてね!」と明記する必要があった
public Hero(Weapon weapon) {
this.weapon = weapon;
}
}
今の主流の書き方(@Autowiredなし)
@Service
public class Hero {
private final Weapon weapon;
// @Autowired がない!でもDIされる!
public Hero(Weapon weapon) {
this.weapon = weapon;
}
}
この下のコードでも、Springの管理人(IoCコンテナ)はこう考えます。
「このHeroクラスを作りたいけど、入口(コンストラクタ)でWeaponを欲しがっているな。入口はこれ1つしかないし、倉庫からWeaponを持ってきて渡してあげよう」
つまり、何も書いていなくても、裏側ではしっかりDIが行われている のです。
現場でコードを見て「あれ?DIのアノテーションがないぞ?」と思ったら、この「コンストラクタ注入(暗黙のDI)」である可能性が高いです。
2. 役割を与えるアノテーションも「DIの一部」
もう一つ重要な点があります。
DIというのは、「渡す側(注入)」だけでなく、「渡される部品を作る側(登録)」もセットで成立する仕組みです。
質問者さんが見たかもしれない @Autowired 以外のアノテーション(例えば @Service や @Controller など)は、DIをしていないのではなく、「私はDIされる準備ができた部品ですよ」と名乗り出ている 状態です。
これらを役割ごとに整理してみましょう。
チームSpringのメンバー(Bean)であることを宣言するアノテーション
以下のマークがついたクラスは、Springの倉庫(コンテナ)に登録され、いつでも誰かに「注入」される準備が整います。
- @Component (基本のメンバー)「私はSpringに管理される部品です」という基本の宣言。
- @Service (サービス)「私はビジネスロジック(計算や判断)を担当します」という宣言。
- @Repository (リポジトリ)「私はデータベースへのアクセスを担当します」という宣言。
- @Controller (コントローラー)「私は画面やWebの通信を担当します」という宣言。
これらは、直接「何かを注入してくれ」という命令ではありませんが、DIのエコシステムに参加するための入場券 です。これらがないと、Springはそもそもそのクラスを認識できず、DIもできません。
ですから、これらも「DIを活用するための重要なアノテーション」と言えます。
3. その他のDI関連アノテーション
さらに補足すると、@Autowired 以外にも「注入してほしい」とお願いするアノテーションは存在します。
- @ResourceJava標準のアノテーションで、名前を指定して注入したいときなどに使われます。
- @Valueクラスなどの部品ではなく、「設定ファイルに書かれた文字や数字」を注入したいときに使います。
これらも立派なDIの一種です。
まとめ
今回の話を整理しましょう。
- @AutowiredがなくてもDIは動くコンストラクタが1つの場合、自動的にDIされるのが今の主流です。
- 他のアノテーションは「部品登録」の役割@Service や @Controller は、「注入される部品(Bean)」になるための宣言です。これらもDIの仕組みの一部です。
「@Autowired が書いてあるところだけがDIだ」と思うと、コードの読み解きで迷子になってしまいます。
「部品どうしが自動でつながる仕組み全体」がDIなんだ、と少し広い視野で捉えてみてください。
今後の学習の指針
今回の疑問が解消されたら、次は実際にコードを書いて「あえて @Autowired を消してみる」実験をしてみませんか?
- Spring Bootで簡単なクラスを2つ作る(使う側と、使われる側)。
- コンストラクタを作って、
@Autowiredをつけずに実行してみる。 - 本当にエラーにならずに動くか確認する。
これを自分の手で確認できると、「なるほど、これが今のSpringか!」と自信がつきますよ。
ぜひ試してみてくださいね。応援しています!
それでは、また次の記事でお会いしましょう。
セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク
投稿者プロフィール
- 代表取締役
-
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。