2012-07-06 181 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