将@SessionScoped CDI Bean注入@Stateless EJB

时间:2013-11-10 15:03:55

标签: java-ee ejb cdi glassfish-4 weld

我想将一个sessioncoped CDI bean注入无状态EJB。在EJB的访问时,应该使用sessionscoped cdi bean的正确实例(即调用者的sessionscope中的那个)。我知道我可以使用有状态的EJB来解决这个问题,但是我真的想知道这是否也可以用CDI解决。由于EJB和Servlet在同一个战争中运行,我假设它们共享同一个线程,容器应该能够在EJB中找出正确的sessioncoped 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关联的CDI bean。因此,如果来自不同浏览器/ http会话的两个客户端访问Servlet,则它们应该获得不同的结果字符串。

我是否需要CDI Provider而不是Instance,如果是,我如何为给定的会话生成正确的bean实例? 我想过可能会得到BeanManager并搜索SessionData的实例,但我不知道我是如何得到正确的。

非常感谢任何帮助,谢谢!

2 个答案:

答案 0 :(得分:4)

好的,现在我觉得有点愚蠢: - (

我绕过了代理提供的上下文bean,没有使用getter / setters进行成员访问。相反,我直接使用了package-private字段,这会阻止代理提供正确的实例。

当我切换到getters / setter时,它开始按预期工作。

答案 1 :(得分:0)

由于client proxies,将长期存在的bean作用域注入到短期的bean(包括EJB的Dependent作用域)中是开箱即用的。

另请参阅Weld reference manual中的相应部分。