springMVC源码简读——2.6 FlashMapManager

概述

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());
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大·风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值