自分が過去にSpring Bootの勉強をしていた時に書いていたソースを振り返ってみると「おや…?」と思う瞬間がありました。
見つけたのは、大量のフィールドインジェクション。
クラスの変数に直接 @Autowired がペタペタ貼ってある、あの光景です。
「あぁ、このソースコードを書いていた頃は、きっとあの頃だったんだな…」と、コードから時代背景が透けて見えるような感覚。これ、エンジニアあるあるですかね?
でも、最近のSpringの流儀だと「フィールドインジェクションは推奨されにくい」なんて言われがち。せっかくなので、DI(依存性注入)の推奨スタイルがどう変わってきたのか、自分の整理がてら歴史を掘り起こしてみました。
① XML時代(設定ファイル時代)
昔は applicationContext.xml という巨大な地図に、「このクラスとこのクラスをガッチャンコしてね」と全部書いていました。(わかる?)
<bean id="myService" class="com.example.MyServiceImpl">
<property name="myRepository" ref="myRepository" />
</bean>こんな具合です。Beanが増えるたびにXMLが数千行になり、管理するだけで日が暮れる。まさに修行の時代でした。
② フィールド注入時代(アノテーション革命)
そこで登場したのが @Autowired。
「フィールドにアノテーションを貼るだけ!?XMLいらないだと?!」と驚きの声が多かったとか。当時の私は「アノテーションってなんだろ?」というレベル感でした。
@Service
public class MyService {
@Autowired // ← これを貼るだけでOK!当時は魔法に見えた
private RepositoryA repositoryA;
@Autowired
private RepositoryB repositoryB;
}これがあるあるのフィールドインジェクション。今でもひと昔前のプロジェクトでよく見かけるのは、この時代の爆発的な流行の名残ですね。
③ コンストラクタ注入時代(現代)
ところが、フィールド注入には「テストがしにくい」「final(不変)にできない」という弱点がありました。JunitのテストコードにMockitoの設定が大変なことに。。。そこで「やっぱりコンストラクタで渡すのが一番硬くて安全だよね」という原点回帰が起こったようです。
@Service
public class MyService {
private final RepositoryA repositoryA;
private final RepositoryB repositoryB;
// Spring 4.3からは、コンストラクタが1つなら @Autowired さえ不要に
public MyService(RepositoryA repositoryA, RepositoryB repositoryB) {
this.repositoryA = repositoryA;
this.repositoryB = repositoryB;
}
}こんな具合です。「書かなくていい(自動で判断してくれる)のが、一番の進化」という境地に達したようです。
④もっと書かなくていい時代
今回いろいろ調べてて、「これ、めっちゃ素敵やん」と個人的に感動したのがLombokの @RequiredArgsConstructor です。
コンストラクタ注入が安全なのは理解した。。でも、正直「コンストラクタを書くのも、面倒だなー。。。」ってずっと思ってたんですよ。
それが、これですよ。
@Service
@RequiredArgsConstructor // ← これでおしまい。コンストラクタを自動生成してくれる
public class MyService {
private final RepositoryA repositoryA; // finalをつけるだけでDI対象になる
private final RepositoryB repositoryB;
}こんな具合です。「final で安全」+「コンストラクタ記述なしで楽」。
これを知ってから、もう昔の書き方には戻れないなと感じています。
フィールドに @Autowired を書かなくなった理由まとめ
2026年現在、フィールド注入が現在は推奨されにくい書き方とされる理由は、主にこの3つのようです。
• 「書き換え」を防げない:final にできないから、後から誰かが中身をすり替えても文句が言えない。
• テストがめんどい:テストの時にモックを差し込もうとすると、テストコードが煩雑になりやすい。
• 循環依存に気づかない:コンストラクタ注入なら、AとBが互いに依存してたら起動時に「無理!」と怒ってくれますが、フィールドインジェクションだと問題の発見が遅れることがある。
調べてみて思ったこと
過去に自分が書いたコードや未だに推奨されないDIになっているコードは、その当時の「最善」を尽くした結果だと思います。タイトル通りエモいわ。
だから否定をする気など全くないけど、新しく作る部分は今の時代の「楽で安全な正解」を取り入れていきたいと思いました。
「お?」と思った違和感を放置せずに調べてみると、技術の歩みが分かって面白いもんですね。
シスナビでは過去を尊重しつつ、今の最善を選び続ける姿勢を大切にしています。