22_1 Spring MVC - ViewResolver系列 - AbstractCachingViewResolver

22_1 Spring MVC - ViewResolver系列 - AbstractCachingViewResolver

一、简介

AbstractCachingViewResolver是一个抽象类,这种视图解析器会把它曾经解析过的视图保存起来,然后每次要解析视图的时候先从缓存里面找,如果找对了对应的视图就直接返回,如果没有就创建一个新的视图对象,然后把它放到一个用于缓存的map中,接着再把新建的视图返回。使用这种视图缓存的方式可以把解析视图的性能问题降到最低。

二、源码解析

2.1 缓存视图的 map

// 默认缓存的大小
public static final int DEFAULT_CACHE_LIMIT = 1024;
// 缓存view的map
private final Map<Object, View> viewAccessCache = new ConcurrentHashMap<>(DEFAULT_CACHE_LIMIT);

2.2 resolveViewName方法的实现

	@Override
	@Nullable
	public View resolveViewName(String viewName, Locale locale) throws Exception {
		if (!isCache()) {
			return createView(viewName, locale);
		}
		else {
			Object cacheKey = getCacheKey(viewName, locale);
			View view = this.viewAccessCache.get(cacheKey);
			if (view == null) {
				synchronized (this.viewCreationCache) {
					view = this.viewCreationCache.get(cacheKey);
					if (view == null) {
						// Ask the subclass to create the View object.
						view = createView(viewName, locale);
						if (view == null && this.cacheUnresolved) {
							view = UNRESOLVED_VIEW;
						}
						if (view != null) {
							this.viewAccessCache.put(cacheKey, view);
							this.viewCreationCache.put(cacheKey, view);
							if (logger.isTraceEnabled()) {
								logger.trace("Cached view [" + cacheKey + "]");
							}
						}
					}
				}
			}
			return (view != UNRESOLVED_VIEW ? view : null);
		}
	}
  • 先通过 isCache() 判断是否启动缓存
  • 如果没有启动缓存,直接通过 createView(viewName, locale) 方法创建视图
  • 如果使用了缓存,则先获取key
    • key的获取通过 getCacheKey(viewName, locale) 获取
  • 在缓存map里获取 view,判断view是不是为null
  • 如果为null,采用双重校验饿方式进行安全创建

2.2.1 isCache()

	public static final int DEFAULT_CACHE_LIMIT = 1024;
	private volatile int cacheLimit = DEFAULT_CACHE_LIMIT;	
	public boolean isCache() {
		return (this.cacheLimit > 0);
	}

2.2.2 createView(String viewName, Locale locale)

创建新视图的方法有具体的子类实现。

	@Nullable
	protected View createView(String viewName, Locale locale) throws Exception {
		return loadView(viewName, locale);
	}

	@Nullable
	protected abstract View loadView(String viewName, Locale locale) throws Exception;

2.2.3 getCacheKey(String viewName, Locale locale)

缓存map中的key的规则

	protected Object getCacheKey(String viewName, Locale locale) {
		return viewName + '_' + locale;
	}
posted @ 2020-09-13 15:36  在线打工者  阅读(211)  评论(0编辑  收藏  举报