使用CDI注入EJB Bean

时间:2015-01-30 04:40:36

标签: java-ee jboss ejb jboss7.x cdi

我试图使用@Inject将EJB单例bean注入CDI bean。但是注入的实例有时是本地的,有时它是远程实例(重新启动时更改)。它不一致。

在下面的示例中,TestService ejb的远程实例被注入到GetTestData cdi托管bean中。但我期待本地实例。并且它也不一致,有时它会注入本地实例。我已经通过在GetTestData类中打印注入的bean来解决这个问题。

请注意,部署包中不包括我的测试类。

知道如何让它始终注入本地实例吗?

EJB Singleton Bean:

@Singleton
@Local(TestService.class)
@Remote(TestServiceRemote.class)
public class TestServiceImpl implements TestService {
    ..
}

CDI Bean:

public class GetTestData {

    @Inject
    TestService testService;

    ....
}

单元测试:

@RunWith(CdiRunner.class)
public class GetTestDataTest {

    @Inject
    private GetTestData getTestData;

    @Produces
    @ProducesAlternative
    @Mock
    private TestService testService;

    .....
}

我使用的是 JBoss 7.1.1-Final 版本(Application Server),而Weld核心版本是 1.1.23-Final

我无法使用@EJB,因为我使用cdi-unit进行测试。

1 个答案:

答案 0 :(得分:4)

首先,请记住,CDI注入不支持开箱即用的远程EJB(通过@Inject注释)。当使用EJB作为CDI bean时,它的远程接口被排除在bean的类型集之外,如here所述。 为了能够使用远程EJB,您必须将其声明为resource

public class ResourceProducers {

@Produces @EJB(ejbLink="../their.jar#TestServiceRemote")
TestServiceRemote remoteService;

}

因此,您所经历的行为可能来自CDI单元,因为CDI不可能在注入点使用远程EJB接口。

我的建议:

  1. 问问自己在应用程序中是否真的需要EJB远程。今天,使用JAX-RS和其他类似websocket的技术,它们有点过时了。
  2. 如果您不需要EJB远程,请将EJB support注释添加到CDI-Unit测试中,它可能有助于框架为您提供预期的EJB行为(单例)。也不要像你那样嘲笑EJB:我不认为CDI-Unit会在你的模拟中复制EJB性质。
  3. 如果您想坚持使用EJB远程,我想您必须切换到更强大的测试框架,如Arquillian。我不是CDI-unit专家,但我认为他们不支持远程EJB。
  4. 如果你正在开始开发,你真的应该考虑使用WildFly应用服务器,下一代JBoss服务器。您将获得Java EE 7和更强大的服务器。