2012-07-06 100 views
3

我有一个JSF管理的session-scopped bean。它也是一个弹簧组件,所以我可以注入一些字段:JSF/Spring Session在用户之间共享

import javax.faces.bean.ManagedBean; 
import javax.faces.bean.SessionScoped; 
import org.springframework.stereotype.Component; 

@ManagedBean 
@SessionScoped 
@Component 
public class EpgBean {...} 

问题是会话在用户之间共享!如果用户执行某些操作并且来自另一台计算机的另一个用户连接,则会看到另一个用户的SessionScoped数据。

是由于Spring的@Component会迫使bean成为单例吗?这件事情的正确方法是什么?

+2

我不使用Spring,但理论上你应该摆脱那些未使用的JSF托管bean注释(因为这只会让你感到困惑;如果你使用另一个框架来管理bean,它们根本没有被使用)并添加(比如'@Scope(“session”)')(它确实默认为“application”作用域,就像JSF在没有声明JSF特定作用域注释时JSF默认为“none”作用域一样)。 – BalusC 2012-07-06 12:18:38

回答

5

我解决了问题,使用弹簧范围注释@Scope("session")而不是JSF @SessionScopped。我猜想,因为spring被配置为FacesEl解析器,所以它是弹簧作用域,JSF作用域被忽略。

+0

对,你也可以这样做! :)我会想念@ViewScoped,虽然... – elias 2012-07-06 12:29:45

+0

这将是有益的,如果你可以标记这个职位为答案。 – 2012-07-06 14:41:56

+0

我试过了,但是在2天之后我就不行了。 – kgautron 2012-07-06 15:39:00

2

我使用的方法是将托管bean保存在JSF容器中,并通过托管属性上的EL将Spring bean注入到它们中。见related question

要做到这一点,设立SpringBeanFacesELResolverfaces-config.xml,使JSF EL可以解决的Spring bean:

<application> 
    ... 
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> 
    ... 
</application> 

之后,你可以注入的Spring bean在@ManagedBean注解的bean是这样的:

@ManagedBean 
@ViewScoped 
public class SomeMB { 
    // this will inject Spring bean with id someSpringService 
    @ManagedProperty("#{someSpringService}") 
    private SomeSpringService someSpringService; 

    // getter and setter for managed-property 
    public void setSomeSpringService(SomeSpringService s){ 
     this.someSpringService = s; 
    } 
    public SomeSpringService getSomeSpringService(){ 
     return this.someSpringService; 
    } 
} 

可能有比这更好的方法,但这是我最近一直在使用的方法。

+0

谢谢,我没有考虑使用ManagedProperty。不过,我相信我的原始方法(声明为spring组件)更好,因为您不必通过EL明确写入注入bean的名称,因为您可以自动装入它们。 – kgautron 2012-07-06 12:19:50