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 @Inject
ed 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!
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