我想将会话范围的CDIbean注入到无状态的EJB中。在访问 EJB 时,应使用会话范围的 cdi bean 的正确实例(即调用方的会话作用域中的实例)。我知道我可以用有状态的 EJB 解决这个问题,但是我真的很想知道这是否也可以用 CDI 解决。由于 EJB 和 Servlet 在同一场战争中运行,我假设它们共享相同的线程,并且容器应该能够在 EJB 中找出正确的会话范围 bean?
例如:
EJB:
@Stateless
@LocalBean
public class StatelessSessionBean {
@Inject
Instance<SessionData> sessionData;
public String testMethod() {
SessionData bean = sessionData.get();
String result = "Retrieved bean " + bean + " with UUID "+ bean.uuid + ". Created on: " + new SimpleDateFormat("dd.MM.yyyy HH:mm").format(bean.creationDate);
return result;
}
}
CDI Bean:
@SessionScoped
public class SessionData implements Serializable {
String uuid;
Date creationDate;
public SessionData() {
uuid = UUID.randomUUID().toString();
creationDate = new Date();
}
}
当我现在访问无状态的EJB时,例如从servlet,我希望testMethod使用与调用者的HTTPSession相关联的CDIbean。因此,如果来自不同浏览器/http 会话的两个客户端访问 Servlet,它们都应该得到不同的结果字符串。
我是否需要 CDI Provider
而不是 Instance
,如果是,如何为给定会话生成正确的 Bean 实例?我想过也许得到BeanManager并搜索SessionData的实例,但我不知道如何获得正确的实例。
任何帮助都非常感谢,谢谢!
好吧,现在我觉得有点愚蠢:-(
我绕过了代理提供的上下文 bean,不使用 getter/setter 进行成员访问。相反,我直接使用了包私有字段,这会阻止代理提供正确的实例。
一旦我切换到getter/setters,它就开始按预期工作。
由于客户端代理,将长寿命的 Bean 作用域注入到短寿命作用域(包括 EJB 的依赖作用域)中是开箱即用的。
另请参阅焊接参考手册中的相应部分。