我需要在Servlet中修改用户 session 对象(SessionScoped bean-CDI),因此我必须以某种方式获取该bean。我通过以下方式使用了注入(inject):

@Inject
private UserSession user;

其中,UserSession是SessionScoped CDI bean。从doPost或doGet servlet方法调用用户方法。
这很完美;每次@Inject批注注入(inject)适当的UserSession bean时,但我不了解如何实现此行为。

我假设用@Inject注释的bean仅被注入(inject)一次(当创建对象-在这种情况下为Servlet实例时),但这显然是错误的假设。

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

最佳答案

CDI使用proxy pattern。注入(inject)的实例实际上不是真实实例,而是一个代理,它根据当前上下文定位实际实例并将所有方法委托(delegate)给它(例如EJB的工作方式)。 UserSession bean的自动生成的类大致如下所示:

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

}
此机制允许您在较宽范围的实例中注入(inject)较窄范围的实例,并允许您仍在当前上下文中获得预期的实例。标准的JSF @ManagedProperty注释不支持它,仅仅是因为它不使用代理,而是直接注入(inject)所需的实例。这就是为什么无法通过@ManagedProperty注入(inject)范围更窄的对象的原因。
也可以看看:
  • 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?
  • 关于servlets - 确切地说,何时@Inject批注启动Servlet中SessionScoped bean的注入(inject)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8658392/

    10-08 22:28
    查看更多