2017-09-11 9 views
1

私はJavaEEとDependency Injectionのコンセプトについてかなり新しいです。しかし、私はそれが使用可能なすべての方法を知らないけれども、私はそれを公正に理解しています。インタフェース、外部ライブラリクラスをJavaEEアプリケーションにインジェクトする方法はありますか?

私は以下のようにローカル・インタフェースを持っている:

@Local 
public interface MyInterfaceLocal { 
    SomeType getMeSometype(); 
} 

このインタフェースはステートレスEJBで実装するクラス。

@Stateless 
public class MyInterfaceImpl { 
    public SomeType getMeSomeType() { 
     //Some implementation details... 
     ExternalLibraryClass externalLib = new ExternalLibrary(arg1, arg2); 
     return externalLib.externalLibMethod(); 
    } 
} 

今の問題は、私はexternalLibをインスタンス化しないよう、これは何らかの方法で注入することができましょうか、でしょうか?たとえば、これがインターフェイスで作成した別のEJBだった場合は、単にEJBコンテナにインスタンス化を処理させ、以下のような@EJB注釈を付けることができます。

私は私を可能にする、ので、私は使用しています外部ライブラリのためにこれを(のようなもの)を行うことができるようにしたい
@Stateless 
public class MyInterfaceImpl { 
    @EJB 
    AnotherInterface anotherInterfaceImpl; 

    public SomeOtherType getMeSomeType() { 
     //Some implementation details... 

     return anotherInterfaceImpl.someMethod(); 
    } 
} 

  1. 変更、現在で使用されている基本的な外部ライブラリ私のコードベースへの最小限の変更。必要に応じてより良いものに変更することができます。
  2. MyInterfaceImplクラスを単体テストしたいときは簡単にモックを注入してください。

私はこれまでのところ、そのパラメータExternalLibraryであるため、手動メソッドパラメータインジェクションのいくつかの種類を実行することができラッパー・メソッドを作成するアット

  1. を見てきました。これにより、私の実装は基本的なライブラリと密接に結びついています。 (または私はそれを正しくやっていません)

  2. Context & Dependency Injectionコンテナを使用して(EJBコンテナと同じように)私はそれが同じではないことを認識しています。 Producersを使用する能力について調査しました。私はProducersがCDIに関して何をするのか理解していますが、私はこれをどのように利用できるかについて私の頭を包み込むことはできませんか?あるいは、私が正しい道にいても?

UPDATE: 私は私がより良いCDIプロデューサーを理解する助けと私はそのアプローチで行く試みたが、別の問題に直面したいくつかの記事を見つけました。だから今、私が持っている:

ExternalLibraryProducer.java

public class ExternalLibraryProducer { 
    @Produces 
    private ExternalLibraryClass1 extrnalLibraryClassProducer() { 
     return new ExternalLibraryClass1("SomeString", 7); 
     //The constructor actually takes a string and another commplex type 
     //as parameters. I am keeping it a little simple here. 
     //I am trying to set the ExternalLibraryClass1() arguments 
     //programmatically at runtime. 
    } 
} 

は、今私が生産するオブジェクトのコンストラクタは、パラメータにとり、文字列と整数を言うことができます。私はQualifierを作成して、これらのパラメータを渡して、私が望むオブジェクトを生成できると考えました。

ExternalLibraryClass1Qualifier.java

@Qualifier 
@Retention(RUNTIME) 
@Target({METHOD}) 
public @interface ExternalLibraryClass1Qualifier { 
    String argument1(); 
    Int argyment2(); //This is actually another complex type. Keeping it 
    //simple here. 
} 

今、私が何をしたいのか、私は引数の値は、(プロパティファイルから、想定する)、実行時にプログラムによって設定することにしたい、です。そして、私はこれを行う方法を理解することができません。最終注射は以下のようになります。

@Stateless 
public class MyInterfaceImpl { 
    @Inject 
    @ExternalLibraryClass1Qualifier(argument1 = "something", argument2 = 7) 
    ExternalLibrary externalLib; 

    public SomeType getMeSomeType() { 
     //Some implementation details... 
     return externalLib.externalLibMethod(); 
    } 
} 

ありがとうございました。

+0

CDIプロデューサは良いアプローチのように見えますが、修飾子の引数はここではそのトリックを行いません - 注入ポイントが一致しませんでした。(生成物が読み込みを行うときには問題はないはずです。プロデューサーの方法だと思います。おそらくアプローチを逆転させ、オブジェクトを作成する際にプロデューサが見えるところに 'argument1'と' argument2'をどこかに保存しておきますか? – Siliarus

答えて

0

CDIプロデューサはここに行く方法ですが、唯一の問題は、それらをどのように構築したいのかということです。

あなたは、引数がプロパティファイルから来ていると言いましたので、私はアプローチを逆転させ、プロデューサメソッドがそのプロパティファイルをチェックして値を抽出するように提案します(または、 ):あなたは明らかに修飾子を必要としないし、単に@Inject ExternalLibraryClass1を行うことができます。これにより

@Produces 
private ExternalLibraryClass1 produceExternalLibraryInstance() { 
    // read the properties from the file or from any cache you use 
    String arg1 = PropertyReader.getarg1(); 
    Integer arg2 = PropertyReader.getArg2(); 
    // create object with those args 
    return new ExternalLibraryClass1(arg1, arg2); 
} 

プロデューサは、ExternalLibraryClass1を注入するオブジェクトを作成するときに基づいて呼び出されます。すぐにプロパティファイルからargsを取得できることを確認してください。

0

ExternalLibraryのプロデューサメソッドでは、オブジェクト作成に必要な引数を受け入れることができます。これらの引数は、CDI createsrで生成できます。

public class ExternalLibraryProducer { 

    private String name; 

    private int age; 

    public ExternalLibraryProducer() { 
     // set name and age from properties file or elsewhere 
     // or you can set them individually on their respective producer methods, but might be costly considering you need to read the properties file twice 
    } 

    @Produces 
    public String name() { 
     return name; 
    } 

    @Produces 
    public int age() { 
     return age; 
    } 

    .... 

    @Produces 
    private ExternalLibraryClass1 extrnalLibraryClassProducer(String name, int age) { 
     // Or you can use them directly here, if you opt to not separate this config from the dependencies 
     return new ExternalLibraryClass1(argument, age); 
    } 
} 
関連する問題