【问题标题】:Dynamic resource injection in EJB3?EJB3 中的动态资源注入?
【发布时间】:2011-09-23 10:40:44
【问题描述】:

我知道如何在 EJB 中进行资源注入以获取 JMS 队列,就像下面的示例一样,很容易获取 QUEUE1。但是如果我有很多队列,并且我不想在有新队列“QUEUE4”时更改代码。

是否可以动态获取资源或任何建议?

@Stateless
public class OrderBean implements Order {

@Resource(name = "A.QCF", mappedName = "A.QCF")
private ConnectionFactory connectionFactory;

@Resource(name = "QUEUE1")
private Queue QUEUE1;

@Resource(name = "QUEUE2")
private Queue QUEUE2;

@Resource(name = "QUEUE3")
private Queue QUEUE3;

    public String sendData(String abc) {
        // ...
    }
}

更新:

感谢 Gonzalo 和 bkail,以下是我的解决方案:

EJB 代码:“QueueName”是来自客户端的参数。

InitialContext initialContext = new InitialContext();
Queue dynamicQueue = (Queue)initialContext.lookup("java:comp/env/" + QueueName);

ejb-jar.xml:

<enterprise-beans>
    <session>
        <<resource-env-ref>>
            <resource-env-ref-name>Queue1</resource-env-ref-name>
            <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
        </<resource-env-ref>>
        <<resource-env-ref>>
            <resource-env-ref-name>Queue2</resource-env-ref-name>
            <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
        </<resource-env-ref>>
    </session>
</enterprise-beans>

当我有一个新队列时,我只需要更改 ejb-jar.xml 并重新启动服务器。

【问题讨论】:

  • 依赖注入本身就是动态的。 “动态资源注入”是什么意思?你想让容器现在知道你想要什么依赖吗?
  • 队列名称 "QUEUE1", "QUEUE2", "QUEUE3", ... 是 EJB 中的硬编码。我想让它成为参数的可配置值或从 INI 读取它。有可能吗?

标签: java jms ejb code-injection


【解决方案1】:

恐怕您必须进行显式 JNDI 查找,以便动态设置要注入的资源。比如:

Queue dynamicQueue = (Queue)initialContext.lookup(dynamicQueueName);

其中 dynamicQueueName 是您设置的变量,具体取决于您用于确定队列名称的任何标准。

【讨论】:

  • 我认为这是一个可行的解决方案,我们已经在我们的旧应用程序 (WebLogic) 中使用它。但是因为我们使用 OpenEJB 进行测试(仍然使用 WebLogic 进行生产),所以我可以在两者中使用 @resource 但我现在不能使用 context.lookup() 来获取资源。我会研究它,谢谢。
【解决方案2】:

如果我理解正确,您想为 Queue 动态声明一个 resource-env-ref(这基本上是 @Resource 正在做的事情)。这没有意义:

Jetty: adding <resource-env-ref> programmatically

【讨论】:

  • 的目的是分离开发者和部署者之间的配置。就我而言,它只是让我更改 XML 中的队列名称。但我需要的是动态添加一个新队列,而不仅仅是更改映射。感谢您的回复,如有遗漏,请告诉我。
  • 动态添加新队列绕过开发者/部署者。如果您打算这样做,您不妨直接查找队列(而不是使用@Resource 或resource-env-ref),这是Gonzalo 建议的。我想您也可以查找 QueueConnectionFactory,但我不是 JMS 专家,所以我不确定。
  • 不需要查找QueueConnectionFactory,因为所有队列都使用相同的QueueConnectionFactory。但是如果要求是动态查找QueueConnectionFactory,那么查找是必要的,谢谢。
【解决方案3】:

读者们,一定有比我更优雅的答案。

可以进行静态参数化初始化,例如来自资源包 (.properties) 文件。 见Andy Gibson(顺便缓存了资源包,不过可以刷新缓存。)

我认为您可能意味着将一个对象发送到一组动态队列中的一个。 就我个人而言,我会注入我自己的队列提供程序 bean,自编程。 看Reconfigure your application at runtime with reloadable property files

【讨论】:

  • reloadable 属性很有用。但是因为我想动态“添加”一个队列,而不是更改队列。我不确定,也许这不适合我的情况。不过还是感谢您的回复,reloadable 属性是配置数据的好模式。
猜你喜欢
  • 2011-03-30
  • 1970-01-01
  • 2019-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-23
  • 2023-04-09
相关资源
最近更新 更多