CDI bean中的资源注入

CDI bean中的资源注入

问题描述:

我不确定这是否行得通,但我正在尝试使用带野生蝇的cdi编写JMS生产者,并坚持将资源注入到cdi托管bean中。

I'm not sure if this is supposed to work, but i'm trying to write a JMS producer with cdi with wildfly and stuck at injecting resources into a cdi managed bean:

public class CdiProducer {
    @Resource(name = "java:jboss/DefaultJMSConnectionFactory")
    @Produces
    QueueConnectionFactory qcf;

    @Resource(name = "java:/queue/HELLOWORLDMDBQueue")
    @Produces
    @Hello
    Queue helloWordQueue;

运行此命令,我得到以下错误:

Running this I'm getting the following error:

JBAS016076:将资源注入CDI托管Bean时出错。找不到名为...

JBAS016076: Error injecting resource into CDI managed bean. Can't find a resource named ...

但是,很奇怪的是,当我将资源复制并粘贴到企业bean中时,一切正常!

What is very strange however is, when i copy&paste the resources into a enterprise bean, everything works!

@Stateless
public class QueueSender {
    @Resource(name="java:jboss/DefaultJMSConnectionFactory")
    QueueConnectionFactory qcf;

    @Resource(name="java:/queue/HELLOWORLDMDBQueue")
    Queue helloWordQueue;

队列定义为:

  <jms-destinations>
     <jms-queue name="HelloWorldQueue">
        <entry name="/queue/HELLOWORLDMDBQueue"/>
        <entry name="java:jboss/exported/queue/HELLOWORLDMDBQueue"/>
     </jms-queue>
  </jms-destinations>

这应该以这种方式工作吗?或者是wildfly中的错误?

Is this supposed to work this way? Or is a bug in wildfly?

我没有Wildfly / JBoss的直接经验,但是我有相同的经验和您与Glassfish一样。在我们的例子中,我们使用 @PersistenceContext 注入 EntityManager ,但是我相信同样的规则也适用。

I don't have direct experience with Wildfly/JBoss, but I had the same experiences as you with Glassfish. In our case we were using @PersistenceContext to inject an EntityManager, but I believe the same rules apply.

焊接文档包含有关统一Java EE资源和CDI的部分。它显示了如何定义生产者字段(更详细地描述在此)将这种资源连接到CDI,这意味着您可以在其他地方使用 @Inject

The Weld documentation has a section about unifying Java EE resources and CDI. It shows how you can define a producer field (described in more detail here) to connect such a resource to CDI in a way that means you can use @Inject elsewhere.


字段具有双重性,因为它们既可以成为Java EE组件环境注入的目标,又可以声明为CDI生产者字段。因此,他们可以定义从组件环境中基于字符串的名称到类型安全注入领域中使用的类型和限定符的组合的映射。我们将表示对Java EE组件环境中的对象的引用的生产者字段称为资源。

Fields have a duality in that they can both be the target of Java EE component environment injection and be declared as a CDI producer field. Therefore, they can define a mapping from a string-based name in the component environment, to a combination of type and qualifiers used in the world of typesafe injection. We call a producer field that represents a reference to an object in the Java EE component environment a resource.

...

资源声明实际上包含两部分信息:
JNDI名称,EJB链接,持久性单元名称或从组件环境获取对该资源的引用所需的其他元数据,以及

A resource declaration really contains two pieces of information: the JNDI name, EJB link, persistence unit name, or other metadata needed to obtain a reference to the resource from the component environment, and the type and qualifiers that we will use to inject the reference into our beans.

示例:

@Produces @Resource(lookup="java:global/env/jdbc/CustomerDatasource") 
@CustomerDatabase Datasource customerDatabase;

其他地方:

@Inject @CustomerDatabase Datasource customerDatabase;

虽然在该页面上没有明确说明,但我认为包含该字段的类必须是Java EE bean,即使用 @ javax.ejb.Stateless @ javax.ejb.Singleton 等EJB注释之一进行注释

While not explicitly stated on that page, I believe the class containing this field has to be a Java EE bean, i.e. annotated with one of the EJB annotations like @javax.ejb.Stateless or @javax.ejb.Singleton.