确切地说,当@Inject注释在Servlet中启动SessionScoped bean的注入时?

Cyb*_*rMJ 6 servlets cdi jsf-2

我需要在Servlet中修改用户会话对象(SessionScoped bean-CDI),所以我必须以某种方式获取该bean.我用以下方式注射:

@Inject
private UserSession user;
Run Code Online (Sandbox Code Playgroud)

UserSession是SessionScoped CDI bean.用户方法是从doPost或doGet servlet方法调用的.这很完美; 每次@Inject注释都会注入相应的UserSession bean,但我不明白这种行为是如何实现的.

我假设用@Inject注释的bean只注入一次(当创建对象 - 本例中的Servlet实例时),但这显然是错误的假设.

那么,这些bean什么时候注入到servlet中?按要求?当有多个UserSession对象时,这种方法如何避免冲突(一个servlet实例 - 处理它的多个线程)?

Bal*_*usC 6

CDI使用代理模式.注入的实例实际上不是真实实例,而是根据当前上下文定位实例的代理,并将所有方法委托给它(就像EJB的工作方式一样).UserSessionbean 的自动生成的类看起来大致如下:

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);
    }

}
Run Code Online (Sandbox Code Playgroud)

此机制允许您在更广范围的实例中注入更窄范围的实例,并允许您仍在当前上下文中获取预期实例.标准JSF @ManagedProperty注释不支持它,仅仅因为它不使用代理,而是直接注入所需的实例.这就是为什么不可能通过注入更窄范围的东西@ManagedProperty.

也可以看看: