2017-10-03 5 views
0

私は固有(修飾) beanをルートレベルのビーン内に、それぞれの親ビーン内のビーンをリクエストオブジェクト内の情報に従って使用したいと考えています。リクエストの値ごとにスプリングを使用する別のbean

のは、私は、要求の特定の種類の特定の実装していると私はリクエストボディオブジェクト内ランタイム(情報の判定値を取得しています。私は、次の要件をフルフィルれる私のコードをstructurizeする必要があるとしましょう。

私は要求内識別値はBの実装、特にCの実装のための要求であればCのメソッドを要求する場合にBの方法を印刷する必要があるサンプルWeb例を以下の検討。InputPayloadシステムに特定の実装を決定するsystemTypeとして識別属性を有する。

----------Controller class--------- 

@RestController 
public class ResourceController { 
    @Autowired 
    private RootInterface i; //Class A will be injected here 

    @PostMapping(path = "/update", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) 
    public Result callInterfaceMethod(@RequestBody InputPayload inputPayload) { 
    return i.callRootInterfaceMethod(inputPayload); 
    } 
} 

----------Service classes--------- 

@Service 
public class A implements RootInterface { 
    @Autowired 
    private D d; 

    @override 
    public Result callRootInterfaceMethod(InputPayload inputPayload) { 
    return d.methodToImplement(inputPayload); 
    } 
} 

public interface D { 
    Result methodToImplement(InputPayload inputPayload); 
} 

@Service 
public class B implements D { 
    @override 
    private Result methodToImplement(InputPayload inputPayload) { 
    system.out.println("Class B method is called"); 
    .... 
    } 
} 

@Service 
public class C implements D { 
    @override 
    private Result methodToImplement(InputPayload inputPayload) { 
    system.out.println("Class C method is called"); 
    .... 
    } 
} 

私にはありません。別の親サービスクラス内に注入されます(最小深度は5と仮定します)。 @Qualifierアノテーションに複数の変数宣言を使用する代わりに、それぞれのサービスクラスを呼び出す方法や、異なる参照を作成する方法はありますか?条件付きブロックの代わりにそれぞれの実装されたメソッドをどのように呼び出すことができますか?

答えて

0

次のことが可能です。

  • は、実装は、入力の属性

    public interface D { 
        Result methodToImplement(InputPayload inputPayload); 
        boolean canProcessInput(InputPayload inputPayload); 
    } 
    
    //autowire all beans of type D 
    @Autowired 
    private List<D> dList; 
    
    @Override 
    public Result callRootInterfaceMethod(InputPayload inputPayload) { 
        for(D d: dList) { 
        if(d.canProcessInput(inputPayload)) { 
         return d.methodToImplement(inputPayload); 
        } 
        } 
        // if there is no bean that is capable of processing the input payload 
        return null; 
    } 
    
  • autowireに基づいてサービスをすべて入力を処理することができているかどうかを確認し、スイッチの条件を追加するDインターフェイス上のメソッドを紹介この

    // autowire all beans with their names 
    @Autowired 
    private Map<String, D> dMap; 
    
    @Override 
    public Result callRootInterfaceMethod(InputPayload inputPayload) { 
        switch(inputPayload.getType()) { 
        case A: { 
         return dMap.get("A").methodToImplement(inputPayload); 
        } 
        case B: { 
         return dMap.get("B").methodToImplement(inputPayload); 
        } 
        // if there is no bean that is capable of processing the input payload 
        default: return null; 
        } 
    } 
    
のようなサービスの各タイプ

私の意見では、最初のオプションは、より明確でスケーラブルです

+0

リストを持つというアイデアは良いです。しかし、私は 'InputPayload'または' inputPayload.getSystemType() 'をさらにサービスクラスに渡す必要があり、' A'/'B'に深さ5のサービスコールがあります。そして、私はすべてのサービスのメソッドシグネチャを変更しないことを好みます。 – GovindS

+0

次に、豆の地図を使って2番目のオプションに行くことができます。影響を受けるすべてのサービスを変更することはありません。新しいDサービスを追加する場合は、手動でこの方法に注目する必要がありますが、すべてのロジックが1か所にあります。 –

関連する問題