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

16,141

This happen because '@Inject Instance<>' is dynamic obtained unlike to '@Inject'

If you do '@Inject' into ApplicationScoped bean then injection is obtained only once so in ApplicationScoped bean will be this same reference for all users

If you call .get() on '@Inject Instance<>' then reference to SSB is obtained dynamically each time when you call .get()

More about injection you can read here: http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html/injection.html

Share:
16,141
Christopher Poile
Author by

Christopher Poile

Updated on June 07, 2022

Comments

  • Christopher Poile
    Christopher Poile almost 2 years

    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 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 MainView, 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 @Injected it will refer to that user's SSB.

    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?

    I'm running on Glassfish 3.1.2.

    Some More Info

    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!