パッケージ jakarta.inject

アノテーション型 Inject


  • @TargetSE({METHODSE,CONSTRUCTORSE,FIELDSE})
    @RetentionSE(RUNTIMESE)
    @DocumentedSE
    public @interface Inject
    注入可能なコンストラクター、メソッド、フィールドを識別します。静的メンバーとインスタンスメンバーに適用できます。注入可能なメンバーは、任意のアクセス修飾子(private、package-private、protected、public)を持つことができます。最初にコンストラクターが注入され、次にフィールド、次にメソッドが注入されます。スーパークラスのフィールドとメソッドは、サブクラスのフィールドとメソッドの前に挿入されます。同じクラス内のフィールド間およびメソッド間での注入の順序は指定されていません。

    注入可能なコンストラクターには @Inject アノテーションが付けられ、0 個以上の依存関係を引数として受け入れます。@Inject は、クラスごとに最大 1 つのコンストラクターに適用できます。

    @Inject ConstructorModifiersopt SimpleTypeName(FormalParameterListopt) Throwsopt ConstructorBody

    @Inject は、他のコンストラクターが存在しない場合、引数のない public コンストラクターではオプションです。これにより、インジェクターはデフォルトのコンストラクターを呼び出すことができます。

    @Injectopt Annotationsopt public SimpleTypeName() Throwsopt ConstructorBody

    注入可能なフィールド:

    • @Inject でアノテーションが付けられています。
    • final ではありません。
    • 有効な名前を持っています。
    @Inject FieldModifiersopt Type VariableDeclarators;

    注入可能なメソッド:

    • @Inject でアノテーションが付けられています。
    • abstract ではありません。
    • 独自の型パラメーターを宣言していません。
    • 結果を返す可能性があります
    • 有効な名前を持っています。
    • 引数として 0 個以上の依存関係を受け入れます。
    @Inject MethodModifiersopt ResultType Identifier(FormalParameterListopt) Throwsopt MethodBody

    インジェクターは、注入されたメソッドの結果を無視しますが、void 以外の戻り値の型は、他のコンテキスト(たとえば、ビルダースタイルのメソッドチェーン)でのメソッドの使用をサポートできます。

    例:

       public class Car {
         // Injectable constructor
         @Inject public Car(Engine engine) { ... }
    
         // Injectable field
         @Inject private Provider<Seat> seatProvider;
    
         // Injectable package-private method
         @Inject void install(Windshield windshield, Trunk trunk) { ... }
       }

    @Inject でアノテーションが付けられた別のメソッドをオーバーライドする @Inject でアノテーションが付けられたメソッドは、インスタンスごとの注入リクエストごとに 1 回だけ注入されます。@Inject でアノテーションされたメソッドをオーバーライドする @Inject アノテーションのないメソッドは注入されません。

    @Inject でアノテーションが付けられたメンバーの注入が必要です。注入可能なメンバーは任意のアクセシビリティ修飾子 ( private を含む) を使用できますが、プラットフォームまたはインジェクターの制限 (セキュリティ制限やリフレクションサポートの欠如など) により、非パブリックメンバーの注入が妨げられる場合があります。

    限定子

    修飾子は、注入可能なフィールドまたはパラメーターにアノテーションを付け、型と組み合わせて、注入する実装を識別することができます。修飾子はオプションであり、インジェクターに依存しないクラスで @Inject とともに使用する場合、単一のフィールドまたはパラメーターにアノテーションを付けることができる修飾子は 1 つだけです。次の例では、修飾子は太字になっています。

       public class Car {
         @Inject private @Leather Provider<Seat> seatProvider;
    
         @Inject void install(@Tinted Windshield windshield,
             @Big Trunk trunk) { ... }
       }

    1 つの注入可能なメソッドが別の注入可能なメソッドをオーバーライドする場合、オーバーライドするメソッドのパラメーターは、オーバーライドされるメソッドのパラメーターから修飾子を自動的に継承しません。

    注入可能な値

    特定の型 T とオプションの修飾子の場合、インジェクターは、次のようなユーザー指定のクラスをインジェクトできる必要があります。

    1. T と割り当て互換
    2. 注入可能なコンストラクターがあります。

    例: ユーザーは外部構成を使用して T の実装を選択する場合があります。それ以上に、どの値が注入されるかは、インジェクターの実装とその構成によって異なります。

    循環依存関係

    循環依存関係の検出と解決は、インジェクター実装の課題として残されています。2 つのコンストラクター間の循環依存関係は明らかな問題ですが、注入可能なフィールドまたはメソッド間に循環依存関係を持つこともできます。

       class A {
         @Inject B b;
       }
       class B {
         @Inject A a;
       }

    A のインスタンスを作成するとき、単純なインジェクターの実装では、B のインスタンスを作成して A にセットし、2 番目の A のインスタンスを作成して B にセットし、2 番目の B のインスタンスを作成して A の 2 番目のインスタンスにセットする、というように無限ループに陥る可能性があります。

    保守的なインジェクターは、ビルド時に循環依存を検出してエラーを生成する可能性があります。その時点で、プログラマーは A または B の代わりに Provider<A> または  Provider<B> を注入することにより、循環依存を破ることができます。提供されたコンストラクターまたはメソッドからプロバイダーで get() を直接呼び出すと、循環依存関連を分割するプロバイダーの機能が無効になります。メソッドまたはフィールドインジェクションの場合、依存関連の 1 つをスコープする(たとえば、シングルトンスコープを使用する)ことで、有効な循環関連を有効にすることもできます。

    関連事項:
    @Qualifier, Provider