为什么要在所有用户之间共享@SessionsScoped EJB?

时间:2012-08-04 09:16:54

标签: java-ee return java-ee-6 cdi

我确信我在这里遗漏了一些东西..但我有一个会话范围的EJB:

@javax.inject.Named
@javax.ejb.Stateful
@javax.enterprise.context.SessionScoped
public class Authenticator implements Serializable
{
...

我希望每个HTTP会话都能看到这个EJB的不同实例吗?

但是,当从多个浏览器(包括在不同的机器上)访问JSF页面时,输出

#{authenticator.hashCode()}

在所有这些上都是一样的(当然还有类的成员属性)。为什么会这样? (我已尝试删除@Stateful注释,但同样适用)。

我正在使用JBoss AS 7.1.0。

编辑:我发现在Authenticator上创建一个方法:

public void getHashCode()
{
   return hashCode();
}

并在EL中引用它作为

#{authenticator.hashCode()}

表明我实际上正在访问bean的不同实例;但为什么会这样呢?我无法理解为什么这两个EL表达式的结果会有所不同。

1 个答案:

答案 0 :(得分:0)

您看到的行为与未经身份验证的HTTP会话一致,因此我假设您没有设置身份验证。因此,如果您在代码中添加以下内容

@Resource
private EJBContext ctx;

public Principal getPrincipal() {
    return this.ctx.getCallerPrincipal();
}

并在测试页面添加

<h:outputText value="#{test.principal}" />
<h:outputText value="#{test.hashCode()}" />

你总能看到相同的输出。对于EJB容器,因为在本地调用中客户端实际上是servlet容器,所以总是会看到相同的输出ANONYMOUS{your hash code here}。每个未经身份验证的http会话都算作一个ANONIMOUS EJB会话,因为客户端始终是相同的 - 您的servlet容器。

尝试设置某种身份验证,您会看到您期望的行为,至少我在Glassfish3 +环境中会这样做。