@RequestScoped CDI injection into @MessageDriven bean
Asked Answered
S

2

6

If I have a request scoped CDI bean injected into a @MessageDriven EJB using JMS, as below, can I assume that any given Foo instance will only be used by a single onMessage invocation at a time?

In other words, in the below example, can I safely use member variables in the Foo object to store state across subroutines, analogously to a JSF @RequestScoped managed bean?

Note that it's ok if the same Foo object gets recycled sequentially from one onMessage call to the next, as long as each MessageDrivenBean instance has its own Foo instance such that two requests processing concurrently would be isolated.

 @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 = ...;
     }
 }
Stevenson answered 15/12, 2011 at 20:55 Comment(0)
T
12

WRT the Request scope / context, the CDI spec in section 6.7.1 says that it will be active for a message driven bean implementing MessageListener. It is also destroyed after the delivery of the message, so you'll have a new instance for each message delivered. Further, section 6.7.3 states that the Application context is also active (as one would expect). Conversation and session scopes are not active.

Terat answered 16/12, 2011 at 21:31 Comment(1)
Awesome. That is exactly what I was hoping, and I confirmed by putting an instance counter on the injected object. (It wasn't doing this at first and it turned out I imported the @RequestScoped annotation from javax.faces instead of the right javax.enterprise one.)Stevenson
E
1

I wonder if this will work. What kind of protocol do you intend to use with the MDB?

MDBs are nearly always invoked asynchronously (e.g. via JMS), so there's no notion of any active request when onMessage() is being called. Typically MDBs are also required to implement an interface matching the protocol they're listening to (e.g. for JMS the MDB needs to implement javax.jms.MessageListener).

Eniwetok answered 15/12, 2011 at 22:35 Comment(1)
yes I'm using JMS. Clarified in the example above. In this context, by "request scope", I'm really trying to say "not singleton" - in other words, a new Foo gets injected into each MDB instance such that two concurrent onMessage handlers don't collide.Stevenson

© 2022 - 2024 — McMap. All rights reserved.