SpringMVC源码-----FlashMapManager

FlashMapManager 

public interface FlashMapManager {
    @Nullable
    FlashMap retrieveAndUpdate(HttpServletRequest var1, HttpServletResponse var2);

    void saveOutputFlashMap(FlashMap var1, HttpServletRequest var2, HttpServletResponse var3);
}

结构图:

可以看出结构图非常简单,抽象类采用模板模式定义整个流程,具体实现类用SessionFlashMapManager通过模板方法提供了具体操作FlashMap的功能。

 功能说明:

  •     实际的Session中保存的FlashMap是List<FlashMap>类型,也就是说一个Session可以保存多个FlashMap,一个FlashMap保存着一套Redirect转发所传递的参数;
  •     FlashMap继承自HashMap,除了用于HashMap的功能和设置有效期,还可以保存Redirect后的目标路径和通过url传递的参数,这两项内容主要用来从Session保存的多个FlashMap中查找当前的FalshMap。

1.AbstractFlashMapManager

          1.1 保存FlashMap的方法         

     public final void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response) {
        if (!CollectionUtils.isEmpty(flashMap)) {
            //首先对flashMap中转发的地址和参数进行编码,这里的request主要是用来获取当前的编码
            String path = this.decodeAndNormalizePath(flashMap.getTargetRequestPath(), request);            
            flashMap.setTargetRequestPath(path);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Saving FlashMap=" + flashMap);
            }
            //设置过期时间,默认值是180秒
            flashMap.startExpirationPeriod(this.getFlashMapTimeout());
            用于获取互斥变量,是模板方法,如果子类返回不为null则同步执行,否则不需要同步
            Object mutex = this.getFlashMapsMutex(request);
            if (mutex != null) {
                synchronized(mutex) {
                    //取回保存的flashMap,如果没有则新建一个
                    List<FlashMap> allFlashMaps = this.retrieveFlashMaps(request);
                    List<FlashMap> allFlashMaps = allFlashMaps != null ? allFlashMaps : new CopyOnWriteArrayList();
                    ((List)allFlashMaps).add(flashMap);
                    //将添加完的list<FalshMap>更新到存储介质中去,是模板方法,由子类实现
                    this.updateFlashMaps((List)allFlashMaps, request, response);
                }
            } else {
                List<FlashMap> allFlashMaps = this.retrieveFlashMaps(request);
                List<FlashMap> allFlashMaps = allFlashMaps != null ? allFlashMaps : new LinkedList();
                ((List)allFlashMaps).add(flashMap);
                this.updateFlashMaps((List)allFlashMaps, request, response);
            }

        }
    }

          1.1.2  子类的模板方法实现

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

    public SessionFlashMapManager() {
    }

    @Nullable
    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) {
        WebUtils.setSessionAttribute(request, FLASH_MAPS_SESSION_ATTRIBUTE, !flashMaps.isEmpty() ? flashMaps : null);
    }

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

 1.2 retrieveAndUpdate方法

       取回FlashMap并更新,这里会在取回的时候删除掉匹配的flashMap,并且会在每次取回的时候都会判断flashMap是否过期,然后过期的都会删除。

public final FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response) {
         //从存储介质session中获取list<FlashMap>,模板方法,子类实现
        List<FlashMap> allFlashMaps = this.retrieveFlashMaps(request);
        if (CollectionUtils.isEmpty(allFlashMaps)) {
            return null;
        } else {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Retrieved FlashMap(s): " + allFlashMaps);
            }
            //检查过期的flashMap,并将那他们设置到mapsToRemove
            List<FlashMap> mapsToRemove = this.getExpiredFlashMaps(allFlashMaps);
            //获取与当前request匹配的FlashMap,并设置到match中
            FlashMap match = this.getMatchingFlashMap(allFlashMaps, request);
            //如果有匹配的则将其添加到mapsToRemove,待下面删除
            if (match != null) {
                mapsToRemove.add(match);
            }
            //删除mapsToRemove中保存的变量
            if (!mapsToRemove.isEmpty()) {
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Removing FlashMap(s): " + mapsToRemove);
                }

                Object mutex = this.getFlashMapsMutex(request);
                if (mutex != null) {
                    synchronized(mutex) {
                        allFlashMaps = this.retrieveFlashMaps(request);
                        if (allFlashMaps != null) {
                            allFlashMaps.removeAll(mapsToRemove);
                            this.updateFlashMaps(allFlashMaps, request, response);
                        }
                    }
                } else {
                    allFlashMaps.removeAll(mapsToRemove);
                    this.updateFlashMaps(allFlashMaps, request, response);
                }
            }

            return match;
        }
    }
 

猜你喜欢

转载自blog.csdn.net/weixin_40792878/article/details/82078359