我需要在 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
annotation 不支持它,只是因为它不使用代理,而是直接注入(inject)所需的实例。这就是为什么无法通过 @ManagedProperty
注入(inject)更窄范围的东西的原因。 .也可以看看:
关于servlets - 确切地说,@Inject 注释何时在 Servlet 中启动 SessionScoped bean 的注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8658392/