ホームページ  >  記事  >  Java  >  なぜ大企業は Spring Boot プロジェクトで @Autowired アノテーションの使用を禁止するのでしょうか?

なぜ大企業は Spring Boot プロジェクトで @Autowired アノテーションの使用を禁止するのでしょうか?

Java后端技术全栈
Java后端技术全栈転載
2023-08-15 16:00:38946ブラウズ

1. 説明


##同社は最近、フレームワークを元の からアップグレードしました。 spring Framerwork 3.0<span style="outline: 0px;font-size: 16px;visibility: visible;"></span>5.0<span style="outline: 0px;font-size: 16px;visibility: visible;"></span> にアップグレードされ、コードを書いているときに突然発見されましたIdea では、属性挿入の @Autowired アノテーションに以下のような警告プロンプトが表示されますが、これは非常にわかりにくいものであり、何年もこのように書かれてきたのです。

#フィールド インジェクションは推奨されません

関連ドキュメントを確認したところ、<span style="outline: 0px;font-size: 16px;visibility: visible;">spring Framerwork 4.0</span> 以降、このプロンプトが表示されるようになったことがわかりました。春以降は推奨されません。 4.0. 代わりに、プロパティ インジェクション、コンストラクター インジェクション、およびセッター インジェクションを使用することをお勧めします。

以下では、Spring フレームワークで使用できるさまざまな種類の依存性注入と、各依存性注入の該当する状況を示します。


2. 依存関係の注入の種類

ただし、 の場合<span style="outline: 0px;font-size: 16px;"></span>Spring Framerwork 5.1.3 のドキュメントでは、主に 2 種類の依存関係注入のみが定義されていますが、実際には 3 種類あります。

###
  • #コンストラクターベースの依存関係注入
  • セッターベースの依存関係注入
  • フィールドベースの依存関係注入

そのうちのフィールドベースの依存関係注入<span style="outline: 0px;font-size: 16px;"> </span> は広く使用されていますが、アイデアやその他の静的コード分析ツールではプロンプト メッセージが表示されるため、お勧めできません。

#この注入方法は、いくつかの公式 Spring ガイドでも見ることができます:

なぜ大企業は Spring Boot プロジェクトで @Autowired アノテーションの使用を禁止するのでしょうか?

2.1コンストラクター ベースの依存関係注入

コンストラクター ベースの依存関係注入では、クラス コンストラクターは @Autowired とマークされ、注入される関連パラメーターが多数含まれています。

@Component
public class ConstructorBasedInjection {

    private final InjectedBean injectedBean;

    @Autowired
    public ConstructorBasedInjection(InjectedBean injectedBean) {
        this.injectedBean = injectedBean;
    }
}

そして、Spring の公式ドキュメントでは、@Autowired アノテーションも省略できます。

public class SimpleMovieLister {

    // the SimpleMovieLister has a dependency on a MovieFinder
    private MovieFinder movieFinder;

    // a constructor so that the Spring container can inject a MovieFinder
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // business logic that actually uses the injected MovieFinder is omitted...
}

基于构造函数注入的主要优点是可以将需要注入的字段声明为final, 使得它们会在类实例化期间被初始化,这对于所需的依赖项很方便。

2.2 基于Setter的依赖注入

在基于setter的依赖注入中,setter方法被标注为 @Autowired。一旦使用无参数构造函数或无参数静态工厂方法实例化Bean,为了注入Bean的依赖项,Spring容器将调用这些setter方法。

@Component
public class SetterBasedInjection {

    private InjectedBean injectedBean;

    @Autowired
    public void setInjectedBean(InjectedBean injectedBean) {
        this.injectedBean = injectedBean;
    }
}

和基于构造器的依赖注入一样,在官方文档中,基于Setter的依赖注入中的 @Autowired也可以省去。

public class SimpleMovieLister {

    // the SimpleMovieLister has a dependency on the MovieFinder
    private MovieFinder movieFinder;

    // a setter method so that the Spring container can inject a MovieFinder
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // business logic that actually uses the injected MovieFinder is omitted...
}

2.3 基于属性的依赖注入

在基于属性的依赖注入中,字段/属性被标注为 @Autowired。一旦类被实例化,Spring容器将设置这些字段。

@Component
public class FieldBasedInjection {
    @Autowired
    private InjectedBean injectedBean;
}

正如所看到的,这是依赖注入最干净的方法,因为它避免了添加样板代码,并且不需要声明类的构造函数。代码看起来很干净简洁,但是正如代码检查器已经向我们暗示的那样,这种方法有一些缺点。


#3. フィールドベースの依存関係注入の欠陥

3.1 不変フィールドは宣言できません

フィールドベースの依存関係注入は、final/immutable として宣言されたフィールドでは機能しません。これらのフィールドはインスタンス化する必要があるためです。クラスがインスタンス化されるとき。不変の依存関係を宣言する唯一の方法は、コンストラクターベースの依存関係注入を使用することです。

#3.2 単一責任の設計原則に違反するのは簡単です

##オブジェクト指向プログラミングでは、5 つの設計原則が定められています。 SOLID はコードの再利用性、可読性、信頼性、保守性を向上させるために広く使用されているアプリケーション (中国では一般に 6 つの設計原則) です。

S in

SOLID # は単一のを表します責任原則、つまり、クラスは 1 つの責任に対してのみ責任を負う必要があり、このクラスによって提供されるすべてのサービスは、そのクラスが担当する責任のみに対応する必要があります。

フィールドベースの依存関係注入を使用すると、頻繁に使用されるクラスに対して、時間の経過とともに、徐々により多くの依存関係がクラスに追加されます。私たちはこれを使用することに非常に満足していますが、クラスを無視するのは簡単です。すでに依存関係が多すぎます。しかし、コンストラクターベースの依存関係注入を使用すると、クラスに依存関係がどんどん追加されるため、コンストラクターがどんどん大きくなり、何かが間違っていることが一目でわかります。

10 個を超えるパラメーターを持つコンストラクターがあるということは、クラスが大規模で包括的な関数のコレクションに変換されており、より小さく簡単な Maintained ブロックに分割する必要があることを示す明確な兆候です。

つまり、プロパティ インジェクションは単一責任の原則を破る直接的な原因ではありませんが、シグナルを隠し、無視しやすくなります。

3.3 依存関係注入コンテナーとの密接な結合

フィールドベースの依存関係注入を使用する主な理由は次のとおりです。ゲッターとセッターの定型コードを避けるか、クラスのコンストラクターを作成します。結局のところ、これは、これらのフィールドを設定する唯一の方法は、Spring コンテナを通じてクラスをインスタンス化し、リフレクションを使用してそれらを注入することであることを意味します。そうしないと、フィールドは null のままになります。

依存性注入設計パターンは、クラスの依存関係の作成をクラス自体から分離し、この責任をクラス注入コンテナーに移すことで、プログラム設計を分離して単一の責任に従うことができます。依存関係逆転の原則 (同様に信頼できる)。したがって、フィールドの自動配線によって実現されるクラスの分離は、クラス注入コンテナー (この場合は Spring) に再度結合することによって最終的に失われ、クラスは Spring コンテナーの外では役に立たなくなります。

これは、単体テストなど、アプリケーション コンテナの外でクラスを使用したい場合、他に可能な方法 (リフレクションを除く) がないため、Spring コンテナを使用してクラスをインスタンス化する必要があることを意味します。 ) 自動配線フィールドを設定します。

3.4 依存関係の非表示

依存関係注入を使用する場合は、パブリック インターフェイス Expose を使用して影響を受けるクラスを明確にする必要があります。これらの依存関係は、コンストラクターで必須の依存関係を公開するか、メソッド (セッター) を使用してオプションの依存関係を公開します。フィールドベースの依存関係注入を使用する場合、これらの依存関係は基本的に外部から隠蔽されます。


#4. 概要

フィールドベースの注入は、どんなにエレガントに見えても多くの欠点があるため、可能な限り避けるべきです。推奨されるアプローチは、コンストラクター ベースおよびセッター ベースの依存関係注入を使用することです。

必要な依存関係については、コンストラクターベースのインジェクションを使用し、依存関係を不変にして、null にならないようにすることをお勧めします。オプションの依存関係については、セッターベースのインジェクションを使用することをお勧めします。

以上がなぜ大企業は Spring Boot プロジェクトで @Autowired アノテーションの使用を禁止するのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はJava后端技术全栈で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。