1. 程式人生 > >springMVC原始碼學習之addFlashAttribute原始碼分析

springMVC原始碼學習之addFlashAttribute原始碼分析

本文主要從falshMap初始化,存,取,消毀來進行原始碼分析,springmvc版本4.3.18。關於使用及驗證請參考另一篇https://www.cnblogs.com/pu20065226/p/10032048.html

1.初始化和呼叫,首先是入springMVC 入口webmvc包中org.springframework.web.servlet.DispatcherServlet中的doService方法進行呼叫

public class DispatcherServlet extends FrameworkServlet
{
  private FlashMapManager flashMapManager;
 
public static final String INPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".INPUT_FLASH_MAP"; protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context);
  //初始化
initFlashMapManager(context); }
private void initFlashMapManager(ApplicationContext context) { try {
    //同級目錄下DispatcherServlet.properties中配置
    //org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
this.flashMapManager = ((FlashMapManager)context.getBean("flashMapManager", FlashMapManager.class
)); if (this.logger.isDebugEnabled()) this.logger.debug("Using FlashMapManager [" + this.flashMapManager + "]"); } catch (NoSuchBeanDefinitionException ex) { this.flashMapManager = ((FlashMapManager)getDefaultStrategy(context, FlashMapManager.class)); if (this.logger.isDebugEnabled()) this.logger.debug("Unable to locate FlashMapManager with name 'flashMapManager': using default [" + this.flashMapManager + "]"); } } protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
   //從session中獲取及session中刪除
   //此處執行的是模板類org.springframework.web.servlet.support.AbstractFlashMapManager中的retrieveAndUpdate方法    FlashMap inputFlashMap
= this.flashMapManager.retrieveAndUpdate(request, response); if (inputFlashMap != null)//轉存request request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap)); } }

AbstractFlashMapManager原始碼如下,

retrieveAndUpdate呼叫實現子類的retrieveFlashMaps取session中的flashmap,呼叫子類updateFlashMaps刪除session的方法

public abstract class AbstractFlashMapManager
  implements FlashMapManager
{

public final FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response) {//從session中取falshmap List allFlashMaps = retrieveFlashMaps(request); if (CollectionUtils.isEmpty(allFlashMaps)) { return null; } if (this.logger.isDebugEnabled()) this.logger.debug("Retrieved FlashMap(s): " + allFlashMaps); List mapsToRemove = getExpiredFlashMaps(allFlashMaps); FlashMap match = getMatchingFlashMap(allFlashMaps, request); if (match != null) { mapsToRemove.add(match); } if (!(mapsToRemove.isEmpty())) { if (this.logger.isDebugEnabled()) this.logger.debug("Removing FlashMap(s): " + mapsToRemove); Object mutex = getFlashMapsMutex(request); if (mutex != null) { synchronized (mutex) { allFlashMaps = retrieveFlashMaps(request); if (allFlashMaps != null) { allFlashMaps.removeAll(mapsToRemove); updateFlashMaps(allFlashMaps, request, response); } } } else { allFlashMaps.removeAll(mapsToRemove);
    //從session中刪除falshmap updateFlashMaps(allFlashMaps, request, response); } }
return match; }
//具體實現在SessionFlashMapManager中

   protected abstract List<FlashMap> retrieveFlashMaps(HttpServletRequest paramHttpServletRequest);

  protected abstract void updateFlashMaps(List<FlashMap> paramList, HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse); 
}

 實現類SessionFlashMapManager中重寫retrieveFlashMaps和updateFlashMaps

public class SessionFlashMapManager extends AbstractFlashMapManager
{
  private static final String FLASH_MAPS_SESSION_ATTRIBUTE = SessionFlashMapManager.class.getName() + ".FLASH_MAPS";

  protected List<FlashMap> retrieveFlashMaps(HttpServletRequest request)
  {
    HttpSession session = request.getSession(false);
    return ((session != null) ? (List)session.getAttribute(FLASH_MAPS_SESSION_ATTRIBUTE) : null);
  }

  protected void updateFlashMaps(List<FlashMap> flashMaps, HttpServletRequest request, HttpServletResponse response)
  {//(!(flashMaps.isEmpty())) ? flashMaps : null)有值時,整個表示式返回null
    WebUtils.setSessionAttribute(request, FLASH_MAPS_SESSION_ATTRIBUTE, (!(flashMaps.isEmpty())) ? flashMaps : null);
  }

  protected Object getFlashMapsMutex(HttpServletRequest request)
  {
    return WebUtils.getSessionMutex(request.getSession());
  }
}

spring-web包org.springframework.web.util.WebUtils中WebUtils.setSessionAttribute

public static void setSessionAttribute(HttpServletRequest request, String name, Object value)
  {
    Assert.notNull(request, "Request must not be null");
    if (value != null) {
      request.getSession().setAttribute(name, value);
    }
    else {//進入此步
      HttpSession session = request.getSession(false);
      if (session != null)
        session.removeAttribute(name);//刪除falshmap
    }
  }


介面類org.springframework.web.servlet.FlashMapManager

public abstract interface FlashMapManager
{
  public abstract FlashMap retrieveAndUpdate(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse);

  public abstract void saveOutputFlashMap(FlashMap paramFlashMap, HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse);
}