2 Replies Latest reply: Mar 28, 2012 6:03 PM by christopherp RSS

Understanding @Inject vs @Inject Instance<> and .get()

christopherp Newbie

I'm a little confused about which to use in the following situation:

 

Suppose the servlet creates an Application that handles the user's http session, and the application is similar to this:

 

    public class Application extends AbstractHTTPApplication {

   

    @Inject

    private Instance<MainView> mainView;

 

    public void setupApplication() {

       this.setView( mainView.get() );

     }

 

Later on I have a `@SessionScoped` bean `SSB` that I want to inject into each user's bean:

 

    @SessionScoped

    public class SSB {}

 

Now, when I tried a regular `@Inject SSB ssb;` as a field in `A`, I do not get a new `SSB` for each user:

 

     public class MainView {

 

         @Inject

         private SSB usersSSB;

 

         public someMethod() {

              usersSSB.doSomething();

              System.identityHashCode( usersSSB );

          }

      }

 

Testing with two users, I get the *same* instance of usersSSB in both user's sessions.  I didn't think this was possible... I thought, since SSB is SessionScoped, a new one will be given to each user session, and no matter where it is @Inject ed it will refer to *that* user's `SSB`.

 

So, instead, I tried:

 

    public class MainView {

 

       @Inject

       private Instance<SSB> usersSSB;

 

       public someMethod() {

             usersSSB.get().doSomething();

             System.identityHashCode( usersSSB.get() );

        }

    }

 

 

Now it reports a different `usersSSB` for each user, finally.

 

What's happening here? When I call `usersSSB.get()` later on in each user's session, will the `usersSSB.get()` return *that same bean* for *that same* user each time?

 

If it helps, I'm running on Glassfish 3.1.2.  Thanks for any help on this. I just want to be sure when I inject a SessionScoped bean, I will be getting the exact same bean for that user, always, until their session ends.  Maybe I should use a different approach?

  • 1. Re: Understanding @Inject vs @Inject Instance<> and .get()
    Marko Lukša Apprentice

    You have only one instance of MainView, so its field usersSSB can only point to one instance of SSB.

     

    Of course, if the field is an Instance<SSB>, it also points to only one instance of Instance<SSB>. However, calling .get() on it can return different instances of SSB, depending on the scope - that's why you get different SSBs for each user/session.

  • 2. Re: Understanding @Inject vs @Inject Instance<> and .get()
    christopherp Newbie

    Hi Marko, thanks for the reply!  I'm honestly having trouble wrapping my head around this. There is a new MainView created for each application, and each application is a SessionScoped bean created by the servlet.  Here's some more code that might explain what's happening (I apologize for the cross-posting from SO, I just wanted to see if a weld expert might be able to figure this out too):

     

    The Application class is being injected into the Servlet on a new HttpServletRequest:

    public abstract class AbstractCdiApplicationServlet extends
       
    AbstractApplicationServlet {
    @Inject
    protected Instance<ApplicationWrapper> wrapper;

    @Override
    protected Application getNewApplication(HttpServletRequest request)
           
    throws ServletException {
       
    return wrapper.get().getApplication();
    }
    ...etc etc

    And the ApplicationWrapper is a SessionScoped bean:

    @SuppressWarnings("serial")
    @SessionScoped
    public class ApplicationWrapper implements Serializable {
    @Inject
    private AbstractCdiApplication application;

    public AbstractCdiApplication getApplication() {
       
    return application;
    }
    }

    Doesn't this mean that calling @Inject SSB usersSSB anywhere in MainView (or any object within that user's session) should give me that user's session-scoped bean, and always that same session-scoped bean, for each user's session? Meaning -- different usersSSB for different users, because each user has a different session.

    After all, the Application itself is a SessionScoped bean, injected into and attached to the user's HTTP Session by the getNewApplication method of the servlet? I mean, it is the Application object that injects and attaches the MainView class, after all, right? So that means MainView is a session-scoped bean, doesn't it?

    I'm just trying to figure out how this all works, I guess. Thanks for the help!