【问题标题】:multiple ejb injections which implement the same interface实现相同接口的多个 ejb 注入
【发布时间】:2015-01-29 17:00:26
【问题描述】:

我对这个 ejb 东西很陌生。有没有可能在一个文件中我可以根据某些标准进行多次注射。

例如

public interface common(){
   public void sayhello();
    }

  beanA
     implements common()

  beanB
       implements common()

都是无状态的 bean

现在我有一个客户端需要根据某些条件触发 hello 方法。例如。如果字符串包含 A,则基于控制台输入说,则应注入 beanA,否则应注入 beanB。 有没有可能?我的下一个问题是,我可以说这个动态注入不是由容器管理的吗?如果是这样,我怎样才能让容器控制?我需要一个示例代码或至少任何教程参考。

提前致谢!!

【问题讨论】:

  • 只是为了让我理解您的用例,如果两个 bean 都是无状态的并实现一个通用接口,那么使用哪一个有什么关系?
  • 他们只是有不同的实现
  • 并且客户端会暴露一个单一的界面...

标签: dependency-injection ejb


【解决方案1】:

不,这不可能。您可能可以使用使用线程本地或会话属性的自定义 CDI 范围来接近,但我不建议这样做。相反,只需注入对两个 EJB 的引用,然后根据需要选择要使用的一个:

@EJB(beanName="BeanA")
Common beanA;
@EJB(beanName="BeanB")
Common beanB;

private Common getCommon(String input) {
    return isBeanAInput(input) ? beanA : beanB;
}

【讨论】:

  • 谢谢bkail....所以在这种情况下,会创建冗余对象,在这种情况下,容器是否有可能删除该对象?
  • 会有一个冗余的proxy对象被创建,但是实际的无状态实例不会被分配(和注入,和PostConstruct'ed等)直到一个方法被调用代理。
【解决方案2】:

你可以这样做:

public interfaces ICommon {
    public void sayhello();
}

@Stateless
@LocalHome
public class BeanA implements ICommon {

    public void sayhello() {
        // say hallo 
    }

}

@Stateless
@LocalHome
public class BeanB implements ICommon {

    public void sayhello() {
        // say hallo 
    }

}

这里是使用 EJB 服务的 CDI“客户端”

@Model
public void MyJSFControllerBean {

    @Inject
    private BeanA beanA;

    @Inject
    private BeanB beanB;

    public String sayhello(final String input) {
        if("a".equals(input)) {
            beanA.sayhello();
        } else {
            beanB.sayhello();
        }

        return "success";
    }

}

或者另一种解决方案是您创建一个 CDI 生产者来创建它。但是你混合了两个不同的概念。但我认为这取决于你的具体用例。

动态注入不存在!使用@Produce 和@Qualifier,您可以控制需要注入的CDI bean 的创建。但这仅适用于 CDI,不适用于 EJB。

这里是 CDI 生产者示例:

public void ICommonProducer {

    @EJB
    private BeanA beanA;

    @EJB
    private BeanB beanB;

    @Produces
    public ICommon produce() {
        final String input = "?????";
        // but here you have the problem that must get the input from elsewhere....

        if("a".equals(input)) {
            beanA.sayhello();
        } else {
            beanB.sayhello();
        }
    }

}

@Model
public void MyJSFControllerBean {

    @Inject
    private ICommon common;

    public String sayhello(final String input) {
        common.sayhello();
        return "success";
    }

}

我还没有测试过这段代码...

【讨论】:

  • 感谢 Stefan,我尝试了没有生产者,但没有使用注入,而是使用 @EJB。我希望这也应该有效。但是,在部署时,我所有的 bean 都已部署,但在调用函数时我收到 noEJB 接收器错误。我不明白为什么:-( 下面是我的代码
  • @produce 对此有何帮助?我的意思是,当使用“@EJB”代理对象时,将以任何方式创建,并且只有在调用该方法时,容器才会如您所说创建一个无状态实例。我在方法 common.sayhello() 上以完全相同的方式编写代码,就我而言,我正在从我的 main 方法执行 Jndi 查找。没有 EJB 接收器时出现错误,不知道为什么!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-25
  • 2014-10-25
  • 2019-09-03
  • 2021-10-18
相关资源
最近更新 更多