1. 程式人生 > >spring mvc @SessionAttributes的坑爹之處

spring mvc @SessionAttributes的坑爹之處

來自springmvc3.2.1官方語句

NOTE: Session attributes as indicated using this annotation

* correspond to a specific handler's model attributes, getting transparently
* stored in a conversational session. Those attributes will be removed once
* the handler indicates completion of its conversational session. Therefore,
* use this facility for such conversational attributes which are supposed
* to be stored in the session temporarily

 during the course of a
* specific handler's conversation.
*

* For permanent session attributes, e.g. a user authentication object,
* use the traditional session.setAttribute method instead.
* Alternatively, consider using the attribute management capabilities of the
* generic {@link org.springframework.web.context.request.WebRequest} interface.

    某種程度上,它意圖讓你用在一種存活時間比session短,比request長的會話中。而對於像使用者身份資訊等,還是應該使用session.setAttribute .

    這段話寫的很模糊,那麼,實際上,哪些物件將會被加入session,然後如何獲取到,然後何時銷燬呢?

    我們一個一個來追查。

    1. 哪些物件何時加入session

    跟蹤一下,  spring 在處理完modelAndView 之後,會呼叫HandlerMethodInvoker.updateModelAttributes,其會遍歷model中的key,如果 key在 SessionAttributes中,則加入 

sessionAttributeStore。   

    2. 如何獲取 session中的物件

    在spring 處理modelAndView之前,先檢查是否有SessionAttributes 註釋,有則獲取了 sessionAttributeStore中 對應的屬性,然後加入了 model中。 

因此如果是在AController裡使用 @sessionAttributes("xx"), 併成功設定了該屬性 , 而在BController 裡沒有使用 @sessionAttributes("xx"), 那麼BController 的方法引數裡,使用 @ModelAttribute("xx") String xx, 是取不到sessionAttributeStore 中的值的。如果你想在其它的Controller獲取session的值就要在Bcontroller前面加@sessionAttributes("xx"),因為要初始化 xx後才能在方法引數中通過@ModelAttribute("xx")去獲取session裡面的值

    3. 何時銷燬

    需要手動呼叫 sessionStatus.setComplete, 才會銷燬 @SessionAttributes 中對應的session屬性 。這裡需要留意,要記得銷燬用不著的session物件。