简体   繁体   English

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

[英]Spring lifecycle issue: the annotation @SessionAttributes makes session attributes live longer than the session itself

here is the code that can reproduce this issue: 这是可以重现此问题的代码:

@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";
    }
}

the first controller puts something in the session if it's not already there. 如果第一个控制器尚不存在,则将其放入会话中。

@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";
    }
}

the second controller kills the session. 第二个控制器终止会话。

and in both jsp files, i have the following code that prints the hashcode of the session object and the hashcode of the session attribute: 在这两个jsp文件中,我都有以下代码来打印会话对象的哈希码和会话属性的哈希码:

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

now if i run the application and visit "firstpage", i'll get this: 现在,如果我运行该应用程序并访问“首页”,我将得到以下信息:

session hash: 1838367636 会话哈希:1838367636

someclass hash: 1075505853 someclass哈希值:1075505853

and then i visit the "secondpage", and will get this: 然后我访问“第二页”,将得到以下信息:

session hash: 842656294 会话哈希:842656294

someclass hash: 1075505853 someclass哈希值:1075505853

we can see that the session itself is changed, because the second controller kills the session. 我们可以看到会话本身已更改,因为第二个控制器终止了该会话。 but the session attribute(of the type SomeClass) remains the same. 但是会话属性(SomeClass类型)保持不变。

then if i try to revisit the "secondpage", the session object changes every time, but the session attribute remains the same. 然后,如果我尝试重新访问“第二页”,则会话对象每次都会更改,但会话属性保持不变。

why does the session attribute(which is supposed to be attached to the session) have a longer lifecycle than the session itself? 为什么会话属性(应该附加到会话)的生命周期比会话本身更长?

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

you can run it with mvn jetty:run to reproduce the issue. 您可以使用mvn jetty:run重现该问题。

The documentation for this annotation isn't particularly clear, but my understanding is that it's used to share values between methods in the same controller . 这个注释的文档不是特别清楚,但是我的理解是,它用于在同一控制器中的方法之间共享值。 As I read the following: 当我阅读以下内容时:

This will typically list the names of model attributes or types of model attributes which should be transparently stored in the session or some conversational storage, serving as form-backing beans between subsequent requests 这通常会列出模型属性的名称或模型属性的类型,这些名称或模型属性的类型应透明地存储在会话或某些会话存储中,用作后续请求之间的表单支持bean

I interpret it to mean that each controller method invocation will be wrapped with a call to (1) load the session attributes before entry, and (2) store them at exit. 我将其解释为意味着每个控制器方法调用都将包含以下调用:(1)在进入之前加载会话属性,(2)在退出时存储它们。 Which would have the behavior that you're seeing. 哪些将具有您所看到的行为。

This is reinforced (imo) by the following in the annotation's javadoc: 注释的javadoc中的以下内容对此进行了增强(imo):

For permanent session attributes, eg a user authentication object, use the traditional session.setAttribute method instead 对于永久会话属性,例如用户身份验证对象,请改用传统的session.setAttribute方法

If they're telling you to use the standard functions to modify the session, it indicates to me that the annotation isn't simply a way to access items in the session. 如果他们告诉您使用标准功能来修改会话,则向我表明,注释不仅仅是访问会话中项目的一种方式。

And for a final data point: if this annotation were the way to manage session data, why have session-scoped beans? 对于最后一个数据点:如果此注释管理会话数据的方式,那么为什么要使用会话范围的bean?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM