我有一些服务实现相同的接口。我想根据数据库中的参数动态使用服务。
我想使用CDI注释,但如果不能,请告诉我如何实现?一个工厂 ?
我们有多个提供者与服务相关联,按照数据库中的规则,我们将使用服务或其他服务
Service1 implements IService1, IGeneralService{
public void run(){...};}
Service2 implements IService2, IGeneralService{
public void run(){...};}
然后我将根据一个国家或其他国家/地区的DB参数使用它。
public class Test{
@IGeneralService service;
public void getRunMethod(String numberService){
service.run() (here it run the right service)
}
}
类似的东西。任何想法 ?
答案 0 :(得分:1)
是的,您的测试课程看起来很像工厂。继续保持现有状态,可能看起来像这样:
public class Test{
@IGeneralService service0;
@IGeneralService service1;
public void getRunMethod(String numberService){
if(numberService == '0')
service0.run()
if(numberService == '1')
service1.run()
}
}
就如何管理该服务列表(地图,列表)而言,您可能会更奇特。但是这里的缺点可能是您必须显式注入每个服务。
您还可以走另一条路线,将BeanManager注入您的工厂:
public class Test{
@Inject
BeanManager bm;
public void getRunMethod(String numberService){
IGeneralService svc = (IGeneralService) bm.getBeans(numberService).iterator().next();
svc.run();
}
}
现在您无需显式注入每个服务。
这是您可以在此处使用的两种基本方法。哪个更好取决于您的用例。
答案 1 :(得分:1)
有一种更清洁的方法。
@interface Provider {
String value(); // provider id retrieved from the db
}
class ProviderImpl extends AnnotationLiteral<Provider> implements Provider {
String providerId;
ProviderImpl(String providerId) { this.providerId = providerId;}
}
然后为您的每个服务提供商适当注释:
@Provider("provider-1")
class ProviderOneImpl implements ServiceProvider {}
然后用法如下:
class ServiceProcessor {
@Any
@Inject
Instance<ServiceProvider> serviceProviders;
void doSomethingAwesome() {
String enabledProvider = getCurrentProviderId();
Provider provider = new ProviderImp(enabledProvider);
ServiceProvider serviceProvider = serviceProviders.select(provider).get();
serviceProvider.run();
}
}
答案 2 :(得分:0)
感谢所有我最终以这种方式实现的人:
How to programmatically inject a Java CDI managed bean into a local variable in a (static) method
有效
答案 3 :(得分:0)
您可以注入de接口:
@Inject
@Any
private Instance <Payment> paymentsLazy;
在您的方法之后,您可以选择实现
Payment object = paymentsLazy.select(Cash.class).get ();