I need to modify a user session object (SessionScoped bean - CDI) in a Servlet, so I have to obtain that bean somehow. I used injection in the following way:
@Inject
private UserSession user;
where UserSession is the SessionScoped CDI bean. user methods are called from either doPost or doGet servlet methods. This works perfectly; every time the @Inject annotation injects the appropriate UserSession bean, but I don't understand how this behavior is achieved.
I assumed that the beans, annotated with @Inject, are injected only once (when the object - Servlet instance in this case - is created), but it is obviously a wrong presumption.
So, when are these beans injected into the servlet? Per request? And how does this approach avoids conflicts (one servlet instance - multiple threads to deal with it) when there are multiple UserSession objects?
The CDI uses the proxy pattern. The injected instance is actually not the real instance, but a proxy which locates the real instance depending on the current context and delegates all methods to it (like as how EJBs work). The autogenerated class of your UserSession
bean looks roughly like this:
public UserSessionCDIProxy extends UserSession implements Serializable {
public String getSomeProperty() {
UserSession instance = CDI.resolveItSomehow();
return instance.getSomeProperty();
}
public void setSomeProperty(String someProperty) {
UserSession instance = CDI.resolveItSomehow();
instance.setSomeProperty(someProperty);
}
}
This mechanism allows you to inject instances of a narrower scope in instances of a broader scope and allows you to still get the expected instance in the current context. The standard JSF @ManagedProperty
annotation doesn't support it, simply because it does not use a proxy, but injects the desired instance directly. That's why it's not possible to inject something of a narrower scope by @ManagedProperty
.
Your answer lies in the C of CDI, which stands for Contexts.
What happens is that not the actual bean is injected, but a proxy. This proxy is contextual and resolves to the actual session scoped bean depending on the context of the caller on who's behalf the proxy is executed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With