2017-04-04 3 views
1

私はDIには新しいですが、突然私はEJBアプリケーションでそれを使用する必要があるので、私はそれを再作成しようとします。依存性注入とコンテナクラス(java-ee 7)

このアプローチには、2つの実装 - 2つの実装を持つコンテナクラスが含まれます。これは、パラメータに応じて、一方または両方の実装で動作します。コンテナはシングルトンのメソッド呼び出しで作成されますが、他のejb beanによって使用されます。

ここで私は他のCDIマネージドクラス(ejb bean)で正しく動作するようにSecurityContainerクラスを作成する方法、またはCDI自体を管理する方法が必要ですか?

私は古い(非CDI)コードを提供しています。パラメータを読み取り、コンテナをインスタンス化:

public class SecurityContainer implements SecurityHelper { 
    private SecurityHelper secPrg; 
    private SecurityHelper secHard; 
    public SecurityContainer(SecurityHelper secPrg, SecurityHelper secHard){ 
     this.secPrg=secPrg; 
     this.secHard=secHard; 
    } 

具体的な実装は今DbWorkerとResponseBuilder EJB豆を注入することがあります。ここでは

@Singleton 
public class MySingleton { 
    private static final MySingleton instance = new MySingleton(); 
    private volatile SecurityHelper securityHelper; // container 
    public void setSecurityHelper(SecurityHelper secHelper){ securityHelper=secHelper; } 
    public SecurityHelper getSecurityHelper(){ return securityHelper; }  
    /* now it has some @Inject....*/  

    public void start(String passwordP, String passwordH) 
      ..... 
     // application work with one or two implementations of security 
     if ("P".equals(DbParams.getServerSecurityFlag())) 
      instance.setSecurityHelper(new SecurityContainer(new SecurityHelperImplP(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()), 
           null));    
     else 
      instance.setSecurityHelper(new SecurityContainer(new SecurityHelperImplP(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()), 
           new SecurityHelperImplH(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()))); 
     securityHelper.createSecurity(passwordP, passwordH); 

は、コンテナクラスです。 SecurityHelperImplHは同じように見えます。私は修飾子、多分プロデューサーが必要と考えていますが、それのルックスではドット

答えて

0

を接続することはできません

public class SecurityHelperImplP implements SecurityHelper { 
    private SecurityPrg securityPrg = null; 

    private DbWorker ora;   // now they are CDI managed 
    private ResponseBuilder builder; 

    public SecurityHelperImplP(DbWorker dbworker, ResponseBuilder bld){ 
     this.ora = dbworker; 
     this.builder = bld; 
    } 

は、あなたはどちらかの道を行く - プロデューサまたは修飾子を。どちらもリファクタリングを必要とし、私にとってはプロデューサーはよりスムーズな方法です。 パラメータを検査し、必要に応じてプロデューサオブジェクト(SecurityContainer)を調整することができます。

まず第一に、あなたのSecurityContainerニーズにフィールド注入点も、そう@Injectを追加する:

@Inject 
private volatile SecurityHelper securityHelper; // container 

は注:CDIを使用しているとき、あなたはしたくない/、setterメソッドを削除することを忘れないでくださいそれが必要。

私たちはそれをどのように作り出していますか?あなたの仕事は基本的にはすでに仕事をしています!必要なのは、それをプロデューサーにして、正しい戻り値のタイプを設定し、パラメーターを適切に取得することだけです。それで、ステップバイステップ:

1)生産方法は、生産方法の

すべてprametersが自動的に別の注射可能な源として考慮されるパラメータ。例えば。あなたは@Inject String passwordPにできるようになりました)。ああ、すぐにはうまくいかず、これらのパラメータを正確に取得する方法がわかりません。農産物の方法はそれはCDIがたびに、それはインスタンスを作成する必要があります呼び出すメソッドです

を動作させる方法

2)。だから、スコープのSecurityHelperにあなたの心を作り上げなければなりません。これは@Singletonの開始メソッドで一度設定されているので、は実行時にを変更しないものと仮定します。そのような場合は、おそらく@ApplicationScopedが必要になります。

3)どのように見えますか?ここで

は、私はそれを誤解していなかったと仮定すると、あなたが望む何をすべきコードです:

@Produces // telling CDI this is how it is supposed to create instances of this type 
@ApplicationScoped // what scope does the produced bean have? 
public SecurityHelper produceSecHelper() { 
    // TODO add logic to retrieve these params! 
    String passwordP; 
    String passwordH; 

    SecurityHelper result; 
    // application work with one or two implementations of security 
    if ("P".equals(DbParams.getServerSecurityFlag()){ 
     result = new SecurityContainer(new SecurityHelperImplP(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()), 
           null); 
    } else { 
     result = new SecurityContainer(new SecurityHelperImplP(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()), 
           new SecurityHelperImplH(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance())); 
    } 
    result.createSecurity(passwordP, passwordH); 
    return result; 
} 

注:CDIはひとりでにに、このメソッドを呼び出します。これを手動で行うことは想定されていません。たとえそうしても、それはCDIによって認識されません。

+0

あなたはこのプロデューサーをどこに置くと思いますか? これまでのところ、私はSecurityContainerをそのまま残しました。 MySingletonは現在CDIで管理され、他のマネージドBeanはmySingletonのgetSecurityHelper()からsecurityContainerを使用します。 – Buch

+0

プロデューサが別のCDI Bean内に存在する限り(CDIがそれを見つけることができるように)、問題はありません。 From CDI 1.2 spec - 'プロデューサメソッドは、マネージドBeanクラスまたはセッションBeanクラスのデフォルトアクセス、パブリック、保護、または非抽象メソッドでなければなりません。 「だから私はそれをあなたにとって便利なところに置いて言う。 – Siliarus

+0

SecurityHelperImplPとSecurityHelperImplHを引数としてプロデューサに渡す必要がありますか?私は修飾子でそれらを渡そうとしましたが、コンパイルエラーを受け取りました – Buch