LoginSignup
0
0

【Java】Springで見かけるDI方法の違い(コンストラクタインジェクション vs @Autowired)

Last updated at Posted at 2023-08-03

日頃の業務でなんだかんだJavaを書きますが、良くわかっていない部分があったのでその解消。

Springフレームワークを使っていますが、他のクラスを利用する際にDIしますよね。
書き方としては、@Autowiredを利用する場合とコンストラクタを利用する場合があると思います。

皆さんはどちらでしょうか。
私が担当しているアプリでは後者のコンストラクタを利用する方が主流です。
せっかくなのでこの違いを整理してみました。

コンストラクタを利用する書き方

HogeValidatorクラスをDIする際こんな感じで書きます。

Main.Java
@Service
public class HogeServiceImpl implements HogeService {
    
    // ① インターフェースのfinal宣言
    private final HogeValidator hogeValidator;

    // ② コンストラクタでのDI
    public HogeService(HogeValidator hogeValidator) {
        this.hogeValidator = hogeValidator;
    }

    @Override
    void doHoge() {
        hogeValidator.validate();
        ...
    }

}

①ではinterfaceをfinalを使ってクラス変数として宣言します。
②のコンストラクタ部分では、HogeValidatorをDIします。

Autowiredを利用する際の書き方

Main.Java
@Service
public class HogeServiceImpl implements HogeService {
    
    // Autowiredを用いたDI
    @Autowired
    private HogeValidator hogeValidator;

    @Override
    void doHoge() {
        hogeValidator.validate();
        ...
    }

}

メリット

コンストラクタ

  1. 他クラスとの依存関係が明白に
    ・一箇所に纏まる、見やすい
  2. メンバ変数をfinalで宣言可能
    ・変数がイミュータブルになり、オブジェクトの安全性が向上する。
    (final宣言ができる、ということ)
    ・スレッドセーフになる
    ・必ずメンバ変数がインスタンス化されてからコンストラクタが走る
     
  3. 依存関係が見つからない場合、コンパイルエラー
    ・早期にバグ修正できる
    ・逆に依存関係を環境変数によって切り替えができる
    (本番では本番用の実装クラス、テストではテスト用のクラスを用いる、というような切り替え)

Autowired

  1. 1行でDIできるのでコードが完結
    ・楽で良いね

デメリット

コンストラクタ

  1. コードが冗長になる
    ・いちいち書くのは、、まあだるい

Autowired

  1. 他クラスとの依存関係が分かりにくくなる(可能性がある)
    ・バラバラに宣言できるので、誰かが変なところで依存関係を作るかもね、ということ
  2. finalで変数宣言できない
    ・上の逆
  3. 依存関係が見つからない場合、実行時エラー
    ・実行しないとバグに気づけないのは怖いね

おわり

どちらがお好みでしょうか。
私はコンストラクタの方を好んでます。
コード書くのだるいですが、安全が確保されている方が好みです。
いずれにせよ、プロジェクト内で書き方が統一されているべきでしょう。

よかったら参考にしてみてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0