当前位置: 首页 > 知识库问答 >
问题:

使用CDI动态加载Beans-EJB3

强阳曜
2023-03-14

我在我的应用程序中使用 EJB3,我想知道我可以在运行时根据某些参数动态注入 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是定期服务

 @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类

 @Services(type = "SingleService" )
 @Stateless
 public class SingleServiceBean implements IService{
 .....
 }

然后我在我的 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();
}

我在eclipse中得到的错误:“方法选择(注释...类型实例中的)不适用于参数(字符串)”

共有2个答案

勾长卿
2023-03-14

第一个日期、句点和请求是运行时参数吗?如果是这样,您只能注入某种基于这些属性创建bean的工厂。

如果这些值在部署时是固定的或至少可配置的,则可以使用生产者。

@Produces
public IService getTimer() {
  IService bean = (IService) initialContext.lookup(jndi+"Bean/local"); 
  bean.initializeTimer(firstDate, period, request);
  return bean;
}

您需要找到一种方法来提供配置值。检查限定符概念或使用System.set/get属性来传输值。

於英朗
2023-03-14

假设您使用的是本地接口,则需要在 CDI(而不是 JNDI 位置)中使用限定符。在你的 impl 上,执行以下操作:

@Local
@Stateless
@MyQualifier("someValue")
public class MyServiceOne implements IService {
    ...
}

其中< code>MyQualifier可以是任何值,甚至是JNDI名称。然后当你想解决它的时候,这样做:

@Inject @Any
private Instance<IService> iServiceInstance;

...

IService service = iServiceInstance.select(new MyQualifierLiteral("someValue")).get();

MyQualifierLiteral这里有一个实现MyQualifierAnnotationLiteral。它应该是这样的:

import javax.enterprise.util.AnnotationLiteral;

public class MyQualifierLiteral extends AnnotationLiteral<MyQualifier> implements MyQualifier {

    private final String value;

    public MyQualifierLiteral(final String value) {
        this.value = value;
    }

    @Override
    public String value() {
        return this.value;
    }

}
 类似资料:
  • 错误: 创建名为“My Controller”的bean时出错:注入autowired依赖项失败;嵌套异常为org.SpringFramework.Beans.Factory.BeanCreationException:无法自动连接字段:private MyService MyController.MyService;嵌套异常为org.SpringFramework.Beans.Factory.B

  • 问题内容: 我正在尝试为我的应用程序创建一个插件系统,我想从简单的事情开始。每个插件都应打包在.jar文件中并实现接口: 现在,我创建了一个打包为.jar的实现,并将其放在主应用程序的plugin /子目录中: 在主应用程序中,我想获取一个实例。我尝试了两种选择,都使用。 1.动态扩展类路径 这使用已知的技巧在系统类加载器上使用反射来避免封装,从而添加类路径。 plugins /目录已按预期添加(

  • 问题内容: 当我尝试使用Ajax加载Google Maps v3时,结果是: 在源代码中,我想用JavaScript document.write();编写。 没有iframe,我该怎么办? 谢谢。 问题答案: 不支持。请使用支持的方法加载API: http://code.google.com/apis/maps/documentation/javascript/tutorial.html#Loa

  • 问题内容: 我查找了语法并搜索了api,但仍然对该过程感到困惑。我还搜索了Stackoverflow。加载类并从中动态创建对象的正确方法是什么?换句话说,我希望用户指定要创建的对象类型,然后创建该类型的对象。我不需要菜单,因为我希望他们能够选择当前目录中的任何类。 问题答案: 假设该类具有无参数构造函数,则最简单的方法是- 参考-java.lang.Class

  • 问题内容: 我正在尝试为我的网站创建页面主题功能。我想使用单独的CSS文件在页面上动态加载相应的主题。 我正在使用此代码: 效果很好,但是如果CSS文件未加载,它不会返回任何信息。 加载时,有什么方法可以捕捉吗?也许通过使用ajax? 问题答案: 加载CSS文件(或其任何其他更改)时,Internet Explorer会触发一个事件。其他浏览器不会触发任何事件,因此您将必须手动检查样式表是否已加载

  •  说明 调用方法: $.f2e.util.getScript(url,cache,fn); 函数说明: 加载js,并提供相关回调 参数说明: 参数名 类型 说明 备注 url string 地址 无 cache boolean 缓存 无 fn function 回调函数 无 脚本 <script> $.f2e.util.getScript(url,true,function(){

  • 问题内容: 我已经编写了一个PropertyUtils类(来自互联网),它将加载属性 而PropertiesUtil类如下所示 稍后,我可以通过调用PropertiesUtil.getProperty()方法来获取属性。 但是现在我要稍作修改,以便如果myApp.properties被用户修改/更改,则应再次加载 可能我需要FileWatcher类 但我的怀疑是 如何使用classpath:myA

  • 本文向大家介绍使用ajax+jqtransform实现动态加载select,包括了使用ajax+jqtransform实现动态加载select的使用技巧和注意事项,需要的朋友参考一下 今天在工作的时候遇到一个问题,页面中公司名称是在项目名称选择后用ajax读取出来的。但是jqtransform是在页面加载完成后调用的,所以导致了公司名称下拉框无法展示最新的数据。 用firebug可以看到数据其实已