Java 使用CDI动态加载bean-EJB3
我在我的应用程序中使用EJB3,我想知道我能否基于一些参数在运行时动态地Java 使用CDI动态加载bean-EJB3,java,ejb-3.0,jndi,cdi,Java,Ejb 3.0,Jndi,Cdi,我在我的应用程序中使用EJB3,我想知道我能否基于一些参数在运行时动态地注入bean 因为我有一个@Local接口,它扩展了几个以不同方式工作的bean。因此,在运行时,我希望根据逻辑加载每个bean。到目前为止,我使用了常规的JNDI查找,但我想使用@Inject来完成它。有没有一种方法可以动态注入bean 这是我现有的查找代码。我在这里将bean名作为jndi传递,并动态构建实例 IService bean = (IService) initialContext.lookup(jndi+"B
注入bean
因为我有一个@Local
接口,它扩展了几个以不同方式工作的bean。因此,在运行时,我希望根据逻辑加载每个bean。到目前为止,我使用了常规的JNDI查找
,但我想使用@Inject
来完成它。有没有一种方法可以动态注入bean
这是我现有的查找
代码。我在这里将bean名作为jndi
传递,并动态构建实例
IService bean = (IService) initialContext.lookup(jndi+"Bean/local");
bean.initializeTimer(firstDate, period, request);
更新
我现在有三颗豆子
第一个bean是SingleServiceBean
@Stateless
public class SingleServiceBean implements IService{
@Override
public void doSomething (){
log.debug("inside do something");
}
private final Log log = LogFactory.getLog(SingleServiceBean.class.getName());
}
第二个bean是PeriodicService
@Stateless
public class PeriodicServiceBean implements IService{
@Override
public void doSomething (){
log.debug("inside do something");
}
private final Log log = LogFactory.getLog(PeriodicServiceBean.class.getName());
}
三豆
@Stateless
public class AsyncServiceBean implements IService{
@Override
public void doSomething (){
log.debug("inside do something");
}
private final Log log = LogFactory.getLog(AsyncServiceBean.class.getName());
}
第二次更新
限定符:
@Qualifier
@Target({ TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
@Documented
public @interface Services {
String type();
}
注释文字
public class ServiceQualifier extends AnnotationLiteral<Services> implements Services{
private static final long serialVersionUID = 6471734834552932687L;
private String type;
public String TypeQualifier(String t) {
this.type = t;
return type;
}
public String type() {
return type;
}
}
然后我在我的bean调用者类中添加以下几行
@Inject
private Instance<IService> iServiceInstance;
public void someMethod() {
// this line gives me error by red underline in .select(...)
IService service = iServiceInstance.select(new ServiceQualifier().TypeQualifier("SingleService")).get();
}
@Inject
私有实例;
公共方法(){
//这一行以红色下划线表示错误。选择(…)
IService service=iServiceInstance.select(新建ServiceQualifier().TypeQualifier(“SingleService”)).get();
}
eclipse中出现错误:“类型实例中的方法选择(注释…)不适用于参数(字符串)”是firstdate、period和request运行时参数吗?如果是这样,您只能注入某种基于这些属性创建bean的工厂
如果这些值在部署时是固定的或至少是可配置的,您可以使用生产者
@Produces
public IService getTimer() {
IService bean = (IService) initialContext.lookup(jndi+"Bean/local");
bean.initializeTimer(firstDate, period, request);
return bean;
}
您需要找到一种方法来提供配置值。检查限定符概念或使用System.set/get属性传输值。是firstdate、period和request运行时参数吗?如果是这样,您只能注入某种基于这些属性创建bean的工厂
如果这些值在部署时是固定的或至少是可配置的,您可以使用生产者
@Produces
public IService getTimer() {
IService bean = (IService) initialContext.lookup(jndi+"Bean/local");
bean.initializeTimer(firstDate, period, request);
return bean;
}
您需要找到一种方法来提供配置值。检查限定符概念或使用System.set/get属性传输值。假设您使用的是本地接口,则需要在CDI(而不是JNDI位置)中使用限定符。在impl上,执行以下操作:
@Local
@Stateless
@MyQualifier("someValue")
public class MyServiceOne implements IService {
...
}
其中MyQualifier
可以有任何值,甚至是JNDI名称。然后,如果要解决此问题,请执行以下操作:
@Inject @Any
private Instance<IService> iServiceInstance;
...
IService service = iServiceInstance.select(new MyQualifierLiteral("someValue")).get();
假设您使用的是本地接口,则需要在CDI(而不是JNDI位置)中使用限定符。在impl上,执行以下操作:
@Local
@Stateless
@MyQualifier("someValue")
public class MyServiceOne implements IService {
...
}
其中MyQualifier
可以有任何值,甚至是JNDI名称。然后,如果要解决此问题,请执行以下操作:
@Inject @Any
private Instance<IService> iServiceInstance;
...
IService service = iServiceInstance.select(new MyQualifierLiteral("someValue")).get();
我不熟悉限定词,有点困惑。我已经更新了我所有的三个bean类,你能详细说明一下吗?我不知道还能怎么详细说明。如果你不清楚限定词,这个网站可能会有所帮助:我用你的答案更新代码。请参阅第二次更新。我得到一个错误“类型实例中的方法选择(注释…)不适用于参数(字符串)”。不知道我哪里错了。你能帮我一下吗,约翰?我哪里出错了?我更新了我的答案,介绍了如何定义注释文字。我不熟悉限定符,有点困惑。我已经更新了我所有的三个bean类,你能详细说明一下吗?我不知道还能怎么详细说明。如果你不清楚限定词,这个网站可能会有所帮助:我用你的答案更新代码。请参阅第二次更新。我得到一个错误“类型实例中的方法选择(注释…)不适用于参数(字符串)”。不知道我哪里错了。你能帮我一下吗,约翰?我哪里出错了?我更新了我的答案,介绍了如何定义注释文字。对不起,Jan,我想在这里使用CDI。所以不再进行上下文查找了。从您最初的帖子中,我假设您需要处理远程EJB。对不起,Jan,我想在这里使用CDI。所以不再进行上下文查找了。从您最初的帖子中,我假设您要处理远程EJB。方法“TypeQualifier”应该返回ServiceQualifier实例,因为.select(..)的参数必须是注释文字,而不是字符串。因此,替换为“返回此项;”并更改此方法的返回类型,所有操作都将正常进行。方法“TypeQualifier”应返回ServiceQualifier实例,因为.select(..)的参数必须是注释文字,而不是字符串。因此,替换为“返回此项;”并更改此方法的返回类型,所有操作都将正常工作。