AbstractCachingViewResolver caches unresolved view names by default ("cacheUnresolved"=true; SPR-8173)

This commit is contained in:
Juergen Hoeller 2011-11-28 22:34:29 +00:00
parent 6991cd9cdf
commit 1bb6d29be2
1 changed files with 19 additions and 15 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2011 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -42,8 +42,8 @@ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSu
/** Whether we should cache views, once resolved */ /** Whether we should cache views, once resolved */
private boolean cache = true; private boolean cache = true;
/** Whether we should attempt to resolve views again if unresolved once */ /** Whether we should refrain from resolving views again if unresolved once */
private boolean cacheUnresolved = false; private boolean cacheUnresolved = true;
/** Map from view key to View instance */ /** Map from view key to View instance */
private final Map<Object, View> viewCache = new HashMap<Object, View>(); private final Map<Object, View> viewCache = new HashMap<Object, View>();
@ -69,9 +69,11 @@ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSu
/** /**
* Whether a view name once resolved to {@code null} should be cached and * Whether a view name once resolved to {@code null} should be cached and
* automatically resolved to {@code null} subsequently. * automatically resolved to {@code null} subsequently.
* <p>Default is "false": unresolved view names are not cached. * <p>Default is "true": unresolved view names are being cached, as of Spring 3.1.
* Note that this flag only applies if the general {@link #setCache "cache"}
* flag is kept at its default of "true" as well.
* <p>Of specific interest is the ability for some AbstractUrlBasedView * <p>Of specific interest is the ability for some AbstractUrlBasedView
* implementations (Freemarker, Velocity, Tiles) to check if an underlying * implementations (FreeMarker, Velocity, Tiles) to check if an underlying
* resource exists via {@link AbstractUrlBasedView#checkResource(Locale)}. * resource exists via {@link AbstractUrlBasedView#checkResource(Locale)}.
* With this flag set to "false", an underlying resource that re-appears * With this flag set to "false", an underlying resource that re-appears
* is noticed and used. With the flag set to "true", one check is made only. * is noticed and used. With the flag set to "true", one check is made only.
@ -84,9 +86,10 @@ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSu
* Return if caching of unresolved views is enabled. * Return if caching of unresolved views is enabled.
*/ */
public boolean isCacheUnresolved() { public boolean isCacheUnresolved() {
return cacheUnresolved; return this.cacheUnresolved;
} }
public View resolveViewName(String viewName, Locale locale) throws Exception { public View resolveViewName(String viewName, Locale locale) throws Exception {
if (!isCache()) { if (!isCache()) {
return createView(viewName, locale); return createView(viewName, locale);
@ -95,15 +98,16 @@ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSu
Object cacheKey = getCacheKey(viewName, locale); Object cacheKey = getCacheKey(viewName, locale);
synchronized (this.viewCache) { synchronized (this.viewCache) {
View view = this.viewCache.get(cacheKey); View view = this.viewCache.get(cacheKey);
boolean isCached = this.cacheUnresolved && this.viewCache.containsKey(cacheKey); if (view == null && (!this.cacheUnresolved || !this.viewCache.containsKey(cacheKey))) {
if (view == null && !isCached) {
// Ask the subclass to create the View object. // Ask the subclass to create the View object.
view = createView(viewName, locale); view = createView(viewName, locale);
if (view != null || this.cacheUnresolved) {
this.viewCache.put(cacheKey, view); this.viewCache.put(cacheKey, view);
if (logger.isTraceEnabled()) { if (logger.isTraceEnabled()) {
logger.trace("Cached view [" + cacheKey + "]"); logger.trace("Cached view [" + cacheKey + "]");
} }
} }
}
return view; return view;
} }
} }