springMVC原始碼學習之addFlashAttribute原始碼分析
阿新 • • 發佈:2018-12-03
本文主要從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); }