springMVC源码简读——2.6 FlashMapManager

    xiaoxiao2025-08-30  9

    概述

    FlashMap 管理器接口,负责重定向时,保存参数到临时存储中

    类图

    接口

    public interface FlashMapManager { /** * 恢复参数,并将恢复过的和超时的参数从保存介质中删除 */ @Nullable FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response); /** * 将参数保存起来 */ void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response); }

    初始化

    initFlashMapManager方法是其初始化的方法,同样在DispatcherServlet中

    //DispatcherServlet.java private void initFlashMapManager(ApplicationContext context) { try { // 从环境中获得指定的bean this.flashMapManager = context.getBean(FLASH_MAP_MANAGER_BEAN_NAME, FlashMapManager.class); if (logger.isTraceEnabled()) { logger.trace("Detected " + this.flashMapManager.getClass().getSimpleName()); } else if (logger.isDebugEnabled()) { logger.debug("Detected " + this.flashMapManager); } } catch (NoSuchBeanDefinitionException ex) { // We need to use the default. // 假如不存在就获取默认的内容 this.flashMapManager = getDefaultStrategy(context, FlashMapManager.class); if (logger.isTraceEnabled()) { logger.trace("No FlashMapManager '" + FLASH_MAP_MANAGER_BEAN_NAME + "': using default [" + this.flashMapManager.getClass().getSimpleName() + "]"); } } }

    和其他组件初始化方法类似,不同的是他的默认值在catch中获取

    实现类

    AbstractFlashMapManager

    saveOutputFlashMap

    保存FlashMap

    AbstractFlashMapManager.java @Override public final void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response) { if (CollectionUtils.isEmpty(flashMap)) { return; } // 首先对flashMap中转发的地址和参数进行编码,这里的request主要是用来获取当前的编码 String path = decodeAndNormalizePath(flashMap.getTargetRequestPath(), request); flashMap.setTargetRequestPath(path); // 设置过期时间,默认值是180秒 flashMap.startExpirationPeriod(getFlashMapTimeout()); // 获得互斥变量的值 Object mutex = getFlashMapsMutex(request); // 不为空进行同步操作 加锁 if (mutex != null) { synchronized (mutex) { // 取回保存的flashMap,如果没有则新建一个CopyOnWriteArrayList List<FlashMap> allFlashMaps = retrieveFlashMaps(request); allFlashMaps = (allFlashMaps != null ? allFlashMaps : new CopyOnWriteArrayList<>()); allFlashMaps.add(flashMap); // 更新FlashMap updateFlashMaps(allFlashMaps, request, response); } } // 不进行同步操作 else { List<FlashMap> allFlashMaps = retrieveFlashMaps(request); allFlashMaps = (allFlashMaps != null ? allFlashMaps : new LinkedList<>()); allFlashMaps.add(flashMap); updateFlashMaps(allFlashMaps, request, response); } } // 并没有实现,交给子类实现 protected abstract void updateFlashMaps( List<FlashMap> flashMaps, HttpServletRequest request, HttpServletResponse response);

    retrieveAndUpdate

    取回FlashMap并更新,每次取回的时候都会判断flashMap是否过期,然后过期的都会删除

    AbstractFlashMapManager.java public final FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response) { // 获取list<FlashMap>,并没有实现,交给子类实现 List<FlashMap> allFlashMaps = retrieveFlashMaps(request); if (CollectionUtils.isEmpty(allFlashMaps)) { return null; } // 获得过期的FlashMap List<FlashMap> mapsToRemove = getExpiredFlashMaps(allFlashMaps); // 获得匹配的FlashMap,假如获取到则添加进mapsToRemove集合中 FlashMap match = getMatchingFlashMap(allFlashMaps, request); if (match != null) { mapsToRemove.add(match); } if (!mapsToRemove.isEmpty()) { // 取得互斥变量,决定使用同步和非同步 Object mutex = getFlashMapsMutex(request); if (mutex != null) { synchronized (mutex) { // 获得所有的FlashMap,然后从中移除到所有的mapsToRemove中的值,然后更新FlashMaps allFlashMaps = retrieveFlashMaps(request); if (allFlashMaps != null) { allFlashMaps.removeAll(mapsToRemove); updateFlashMaps(allFlashMaps, request, response); } } } else { allFlashMaps.removeAll(mapsToRemove); updateFlashMaps(allFlashMaps, request, response); } } return match; }

    SessionFlashMapManager

    AbstractFlashMapManager的子类,实现了关键的updateFlashMaps

    updateFlashMaps

    从HTTP session保存指定的FlashMap

    SessionFlashMapManager.java @Override protected void updateFlashMaps(List<FlashMap> flashMaps, HttpServletRequest request, HttpServletResponse response) { // 核心就是把参数保存到了session中,通过参数进行置空或保存值 WebUtils.setSessionAttribute(request, FLASH_MAPS_SESSION_ATTRIBUTE, (!flashMaps.isEmpty() ? flashMaps : null)); }

    getFlashMapsMutex

    获得互斥的变量Mutex

    SessionFlashMapManager.java protected Object getFlashMapsMutex(HttpServletRequest request) { return WebUtils.getSessionMutex(request.getSession()); }
    最新回复(0)