2011-12-15 143 views
5

如果我有使用JMS注入到@MessageDriven EJB中的请求作用域CDI bean,我可以假设任何给定的Foo实例一次只能被一个onMessage调用使用?@RequestScoped CDI注入到@MessageDriven bean

换句话说,在下面的示例中,我可以安全地使用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 = ...; 
    } 
} 

回答

10

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

+0

太棒了。这正是我所希望的,并且我通过将实例计数器放置在注入对象上进行了确认。 (它一开始并没有这样做,事实证明我从javax.faces中导入了@ RequestScoped注解,而不是正确的javax.enterprise注解。) – wrschneider 2011-12-16 22:16:56

1

我不知道这是否会奏效。你打算使用什么样的协议与MDB?

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

+0

是的我正在使用JMS。在上面的例子中说明。在这种情况下,通过“请求范围”,我真的试图说“不是单例” - 换句话说,一个新的`Foo`被注入到每个MDB实例中,使得两个并发的`onMessage`处理程序不会发生冲突。 – wrschneider 2011-12-16 15:42:41