我需要在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)范围更窄的对象的原因。也可以看看:
关于servlets - 确切地说,何时@Inject批注启动Servlet中SessionScoped bean的注入(inject)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8658392/