Java cdi bean 中的资源注入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22463102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 15:53:38  来源:igfitidea点击:

resource injection in cdi bean

javajmscdiwildfly

提问by mglauche

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:

我不确定这是否应该有效,但我正在尝试使用带有 Wildfly 的 cdi 编写 JMS 生产者,并坚持将资源注入 cdi 托管 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: Error injecting resource into CDI managed bean. Can't find a resource named ...

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

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

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

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

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

Queue is defined as:

队列定义为:

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

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

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

回答by andersschuller

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 @PersistenceContextto inject an EntityManager, but I believe the same rules apply.

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

The Weld documentationhas 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 @Injectelsewhere.

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

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.

...

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.

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

...

资源声明实际上包含两条信息:JNDI 名称、EJB 链接、持久性单元名称或从组件环境获取资源引用所需的其他元数据,以及我们将用于注入引用的类型和限定符到我们的豆子里。

Example:

例子:

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

Elsewhere:

别处:

@Inject @CustomerDatabase Datasource customerDatabase;

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.Statelessor @javax.ejb.Singleton.

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

回答by Jimeh

Late to the party, but I ran into this same issue. When using @resource on a CDI managed bean the JNDI was always getting prepended with 'java:comp/env/'. To fix this I changed nameto lookupwhen using @resourceoutside an enterprise bean.

聚会迟到了,但我遇到了同样的问题。在 CDI 托管 bean 上使用 @resource 时,JNDI 总是以“java:comp/env/”开头。为了解决这个问题,我在企业 bean 外部使用时更改name为。lookup@resource

@Resource(lookup = "java:/ConnectionFactory")
private ConnectionFactory connectionFactory;