Egor Erofeev:
私は、アプリケーションがJBossのEAP 7に配備されたJavaEE 7を使用して、Javaでデータベース・プロシージャに保存されているいくつかの古いロジックを書き換えるためのタスクを持っています。
重要な機能は、したがって、我々はすぐに生産に一部のサービスの古いものと新しい実装を切り替えることができるようにするためには、スイッチャーのいくつかの並べ替えを持っている必要があります。
生憎私たちも、重大な問題が発生した場合には、すぐに新しいバージョンを提供し、展開することができません。だから我々は、データベーステーブルの形で、このようなスイッチャーを導入する必要があります。
優れた保守性を提供するために、私は、スイッチャーに基づいて古い/新しい実装を注入するためにCDIを使用したいと思います。
私が見る最も単純な方法は、CDIプロデューサーを利用することです。プロデューサーの方法でDB-Requestを作るために良い解決策になるだろうか?
私の例:
@ApplicationScoped
public class NewServiceProducer {
@Inject
private ImplementationSwitcherDAO implementationSwitcherDAO;
@Produces
@RequestScoped
public NewService produceNewService(){
//a DB-Call is done here
boolean useOldVersion = implementationSwitcherDAO.isUseOldVersionForService("NewService");
if(useOldVersion){
return CDI.current().select(NewServiceOldImpl.class).get();
}
return CDI.current().select(NewServiceImpl.class).get();
}
}
レアードネルソン:
私は本当に「良い習慣」という質問にコメントすることはできませんが、答えに値するここで質問があります。
あなたが欲しいものを行うには、次の、両方ではないいずれかを実行する必要がありますが、:
- ていることを確認してください
NewServiceOldImpl.class
とNewServiceImpl.class
んではない持っているNewService
の彼らのセットにBeanタイプ - 拒否権
NewServiceOldImpl.class
とNewServiceImpl.class
完全に
あなたがしようとそうでない場合は、二つの可能性、および、他のすべてが等しいがあるだろう、CDIは、いくつかの種類で失敗します。@Inject
NewService
AmbiguousResolutionException
私はこのようなソリューションを実装します:
// Let's assume that NewServiceImpl is a regular managed bean
@RequestScoped
@Typed({ NewServiceImpl.class, Object.class }) // ...or whatever, but not NewService.class
public class NewServiceImpl { /*...*/ }
// Let's assume that NewServiceOldImpl is a regular managed bean
@RequestScoped
@Typed({ NewServiceOldImpl.class, Object.class }) // ...or whatever, but not NewService.class
public class NewServiceOldImpl { /*...*/ }
// Then somewhere else:
@Produces
@RequestScoped
private static NewService produceNewService(final NewServiceOldImpl oldImpl,
final NewServiceImpl newImpl) {
if (implementationSwitcherDAO.isUseOldVersionForService("NewService")) {
return oldImpl;
}
return newImpl;
}