lundi 29 juin 2015

What is the scope of @Stateless EJB 3 bean? When are dependency injections processed?

I read the following question below, but have some follow-up questions and confirmations:

Scope of Stateless Bean

This is really confusing point and reading the WELD documentation doesn't seem to explicitly mention how these situations are handled, which is kind of frustrating. It has a lot of verbiage but doesn't seem to provide any simple code examples that basically illustrate WHEN the equivalent of the new XXX() and setXXX() methods are called by the container within different contexts, which is basically all this CDI nightmare is doing for us (and for some reason this is a good idea?). I guess it is even more confusing when you throw JSF managed beans into the mix, which is in itself another disaster since JSF has it's own managed beans that came before CDI.

Q: What is the scope of a bean declared @Stateless? When when the @Inject annotations be processed (and thus when will @PostConstruct be called)?

My understanding is that it is basically @ApplicationScoped as described in the answer above, in so far as the container will pool instances and re-use them when possible. When the container retrieves a pooled instance that is already created, it will not re-inject the @Inject dependencies and thus will not call @PostConstruct again. However, I thought if no scope was declared, each bean should be considered @Dependent scoped, which means at each Injection point a new object is created and thus dependencies re-injected, but this seems not to be the case. Is this different because this an EJB bean and not a pure CDI bean?

Additional questions, assuming the above is correct:

  1. Is there a way to force it to re-inject all of these dependencies before each method call in a client, which is for example a JSF ViewScoped bean?

  2. Does it matter if the client who itself injected the @Stateless EJB used @Inject or @EJB before calling any of its methods?

Take the following example:

@Stateless
public class MyEJB implements MyEjbInterface {
    @Inject MyOtherObject myotherObject;

    void setMyOtherObject(MyOtherObject myotherObject) { ... }
    void method() { ... }
}

@ViewScoped
public class MyViewScopedBean {
   @Inject MyEjbInterface a;
   @EJB MyEjbInterface b;

   void a() {
      a.method();
   }

   void b {
     b.method();
   }
}

So in this example, when will an actual new MyEJB be created (not the proxy object)? When will setMyOtherObject be invoked? How can I force setMyOtherObject to be invoked before every method call by the container without explicitly invoking it myself?

And finally, how does this change MyOtherObject is created by a CDI producer and is not a CDI managed bean. Does the scope of the producer matter?

Aucun commentaire:

Enregistrer un commentaire