Spring生命周期问题:注释@SessionAttributes使会话属性比会话本身更长寿

时间:2013-07-01 14:36:12

标签: java spring session session-state lifecycle

这是可以重现此问题的代码:

@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() %>

现在如果我运行应用程序并访问“firstpage”,我会得到这个:

  

会话哈希:1838367636

     

someclass hash:1075505853

然后我访问“secondpage”,并得到这个:

  

会话哈希:842656294

     

someclass hash:1075505853

我们可以看到会话本身已更改,因为第二个控制器会终止会话。但是session属性(SomeClass类型)保持不变。

然后,如果我尝试重新访问“secondpage”,会话对象每次都会更改,但会话属性保持不变。

为什么会话属性(应该附加到会话)的生命周期比会话本身更长?

PS:完整的代码在这里:https://github.com/cuipengfei/One-hundred-thousand-why/tree/master/20130701SessionAttributesLifeCycle/SpringMVC

你可以使用mvn jetty运行它:运行以重现问题。

1 个答案:

答案 0 :(得分:1)

此注释的documentation不是特别清楚,但我的理解是它用于在同一控制器中的方法之间共享值。当我读到以下内容时:

  

这通常会列出模型属性的名称或模型属性的类型,这些属性应该透明地存储在会话或某些会话存储中,作为后续请求之间的表单支持bean

我将其解释为每个控制器方法调用都将通过调用包装(1)在进入之前加载会话属性,以及(2)将它们存储在出口处。哪个会有你所看到的行为。

注释的javadoc中的以下内容加强了(imo):

  

对于永久会话属性,例如用户身份验证对象,请使用传统的session.setAttribute方法

如果他们告诉您使用标准功能修改会话,则表明注释不仅仅是访问会话中项目的方式。

对于最终数据点:如果此注释 是管理会话数据的方式,那么为什么要使用会话范围的bean?