【问题标题】:@RequestScoped CDI injection into @MessageDriven bean@RequestScoped CDI 注入到 @MessageDriven bean
【发布时间】:2012-01-04 02:32:53
【问题描述】:

如果我使用 JMS 将请求范围的 CDI bean 注入到 @MessageDriven EJB 中,如下所示,我是否可以假设任何给定的 Foo 实例一次只能由单个 onMessage 调用使用?

换句话说,在下面的示例中,我是否可以安全地使用 Foo 对象中的成员变量来跨子例程存储状态,类似于 JSF @RequestScoped 托管 bean?

请注意,如果相同的 Foo 对象从一个 onMessage 调用到下一个调用顺序回收,则可以,只要每个 MessageDrivenBean 实例都有自己的 Foo 实例,这样两个请求会同时处理孤立。

 @MessageDriven
 public class MessageDrivenBean implements MessageListener {
    @Inject 
    private Foo foo;

    public void onMessage(Message m) {
      foo.doSomething();
    }
 }

 @Named
 @RequestScoped
 public class Foo {
   private String property;
     public void doSomething() {
       property = ...;
     }
 }

【问题讨论】:

    标签: jakarta-ee jms java-ee-6 cdi message-driven-bean


    【解决方案1】:

    WRT 请求范围/上下文,第 6.7.1 节中的 CDI 规范说它将对实现 MessageListener 的消息驱动 bean 处于活动状态。它在消息传递后也会被销毁,因此您将为每条传递的消息创建一个新实例。此外,第 6.7.3 节指出应用程序上下文也是活动的(正如人们所期望的那样)。对话和会话范围不活跃。

    【讨论】:

    • 太棒了。这正是我所希望的,我通过在注入的对象上放置一个实例计数器来确认。 (一开始并没有这样做,结果我从 javax.faces 导入了 @RequestScoped 注释,而不是正确的 javax.enterprise 注释。)
    【解决方案2】:

    我想知道这是否可行。您打算在 MDB 中使用哪种协议?

    MDB 几乎总是异步调用(例如通过 JMS),因此在调用 onMessage() 时没有任何活动请求的概念。通常,MDB 还需要实现与它们正在侦听的协议相匹配的接口(例如,对于 JMS,MDB 需要实现 javax.jms.MessageListener)。

    【讨论】:

    • 是的,我正在使用 JMS。在上面的例子中说明了。在这种情况下,通过“请求范围”,我真的想说“不是单例”——换句话说,一个新的Foo 被注入到每个 MDB 实例中,这样两个并发的onMessage 处理程序就不会发生冲突。
    猜你喜欢
    • 2014-06-02
    • 2015-07-14
    • 2019-08-04
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 2013-12-07
    相关资源
    最近更新 更多