2013-07-01 53 views
0

這裏不再是可以重現此問題的代碼:春季生命週期的問題:註釋@SessionAttributes使會話屬性過得比會議本身

@Controller 
public class FirstController { 
    @RequestMapping(value = "firstpage", method = GET) 
    public String myHander(HttpSession httpSession) { 
     if (httpSession.getAttribute("someClass") == null) { 
      httpSession.setAttribute("someClass", new SomeClass()); 
     } 
     return "firstpage"; 
    } 
} 

第一控制器把東西在會議上,如果它不是已經存在。

@Controller 
@SessionAttributes(types = SomeClass.class) 
public class SecondController { 

    @RequestMapping(value = "secondpage", method = GET) 
    public String myHandler(SomeClass someClass, HttpSession httpSession) { 
     //asking spring for the SomeClass parameter, that's why we put it in the annotation. 
     System.out.print(someClass.hashCode()); 

     httpSession.invalidate(); 

     return "secondpage"; 
    } 
} 

第二個控制器殺死會話。

,並在這兩個JSP文件,我有以下代碼打印會話對象的哈希碼和會話屬性的哈希碼:

session hash: 
<%= session.hashCode() %> 
<br/> 
someclass hash: 
<%= session.getAttribute("someClass").hashCode() %> 

現在如果我運行應用程序,並參觀「第一頁」,我會得到這樣的:

會議散列:1838367636

SomeClass的哈希:1075505853

,然後我參觀 「secondpage」,並會得到這樣的:

會議散列:842656294

SomeClass的哈希:1075505853

,我們可以看到,會議本身發生變化,因爲第二個控制器殺死了會話。但會話屬性(類型SomeClass)保持不變。

然後,如果我嘗試重新訪問「第二頁」,會話對象每次都會更改,但會話屬性保持不變。

爲什麼會話屬性(應該附加到會話中)具有比會話本身更長的生命週期?

PS:完整的代碼是在這裏:https://github.com/cuipengfei/One-hundred-thousand-why/tree/master/20130701SessionAttributesLifeCycle/SpringMVC

你可以用MVN碼頭運行:運行重現該問題。

回答

1

該註釋的documentation不是特別清楚,但我的理解是,它用於在同一控制器中的方法之間共享值。當我閱讀以下內容:

這通常會列出名稱的模型屬性或類型的模型的屬性應透明地保存在session或某些會話存儲,作爲後續請求

之間的形式,支持豆

我將其解釋爲意味着每個控制器方法調用將被包裝成調用(1)在進入之前加載會話屬性,以及(2)將它們存儲在出口處。哪一個會有你所看到的行爲。

這是增強(IMO)通過註釋的Javadoc如下:

對於永久會話屬性,例如用戶認證對象,使用傳統的session.setAttribute方法代替

如果他們告訴你要使用標準的功能修改會話,它表明我的註釋是不是一個簡單的方式來訪問項目在會話中。

對於最終數據點:如果此註釋管理會話數據的方式,爲什麼會話範圍的bean?