Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When, exactly, @Inject annotation initiates injection of SessionScoped bean in Servlet?

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?

like image 283
CyberMJ Avatar asked Dec 28 '11 16:12

CyberMJ


2 Answers

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.

See also:

  • Backing beans (@ManagedBean) or CDI Beans (@Named)?
  • Get JSF managed bean by name in any Servlet related class
  • When using @EJB, does each managed bean get its own @EJB instance?
  • How to choose the right bean scope?
like image 52
BalusC Avatar answered Oct 06 '22 21:10

BalusC


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.

like image 45
Arjan Tijms Avatar answered Oct 06 '22 23:10

Arjan Tijms