2011-12-15 98 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