Understanding cdi Instance<> and .get() vs @Inject
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
Christopher Poile
Updated on June 07, 2022Comments
-
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
beanSSB
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 inMainView
, I do not get a newSSB
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'sSSB
.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 theusersSSB.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 aSessionScoped
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 aSessionScoped
bean, injected into and attached to the user's HTTP Session by thegetNewApplication
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!