SpringMVC 源码解析AbstractCachingViewResolver自定义缓存

来源:互联网 发布:网络架构培训 编辑:程序博客网 时间:2024/06/12 18:31
AbstractCachingViewResolver中使用了两个Map用于缓存View视图对象,一个是ConcurrentHashMap在线程安全的前提下提供了较好的并发访问能力,效率较高,另一个是LinkedHashMap保证了值的有序性,同时它有方法是删除最前保存的值,removeEldestEntry(),返回true时表示达到了最大空间。删除值。返回false就是没有达到上线,最常使用的ConcurrentHashMap获取缓存数据,当操作缓存时同时操作ConcurrentHashMap、LinkedHashMap,两者结合起来非常方便,值得我们学习与使用。
/** The maximum number of entries in the cache */private volatile int cacheLimit = DEFAULT_CACHE_LIMIT;/** Whether we should refrain from resolving views again if unresolved once */private boolean cacheUnresolved = true;/** Fast access cache for Views, returning already cached instances without a global lock */private final Map<Object, View> viewAccessCache = new ConcurrentHashMap<Object, View>(DEFAULT_CACHE_LIMIT);/** Map from view key to View instance, synchronized for View creation */@SuppressWarnings("serial")private final Map<Object, View> viewCreationCache =new LinkedHashMap<Object, View>(DEFAULT_CACHE_LIMIT, 0.75f, true) {@Overrideprotected boolean removeEldestEntry(Map.Entry<Object, View> eldest) {if (size() > getCacheLimit()) {viewAccessCache.remove(eldest.getKey());return true;}else {return false;}}};
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);}}