提交 86557f25 编写于 作者: J Juergen Hoeller

ConcurrentMapCacheManager recreates caches when initializing ClassLoader

Issue: SPR-14314
上级 cf0a0cd5
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2016 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.
...@@ -95,6 +95,7 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache { ...@@ -95,6 +95,7 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
* (adapting them to an internal null holder value) * (adapting them to an internal null holder value)
* @param serialization the {@link SerializationDelegate} to use * @param serialization the {@link SerializationDelegate} to use
* to serialize cache entry or {@code null} to store the reference * to serialize cache entry or {@code null} to store the reference
* @since 4.3
*/ */
protected ConcurrentMapCache(String name, ConcurrentMap<Object, Object> store, protected ConcurrentMapCache(String name, ConcurrentMap<Object, Object> store,
boolean allowNullValues, SerializationDelegate serialization) { boolean allowNullValues, SerializationDelegate serialization) {
...@@ -107,13 +108,15 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache { ...@@ -107,13 +108,15 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
this.serialization = serialization; this.serialization = serialization;
} }
/** /**
* Return whether this cache stores a copy of each entry ({@code true}) or * Return whether this cache stores a copy of each entry ({@code true}) or
* a reference ({@code false}, default). If store by value is enabled, each * a reference ({@code false}, default). If store by value is enabled, each
* entry in the cache must be serializable. * entry in the cache must be serializable.
* @since 4.3
*/ */
public final boolean isStoreByValue() { public final boolean isStoreByValue() {
return this.serialization != null; return (this.serialization != null);
} }
@Override @Override
......
...@@ -39,7 +39,7 @@ import org.springframework.core.serializer.support.SerializationDelegate; ...@@ -39,7 +39,7 @@ import org.springframework.core.serializer.support.SerializationDelegate;
* caching scenarios. For advanced local caching needs, consider * caching scenarios. For advanced local caching needs, consider
* {@link org.springframework.cache.jcache.JCacheCacheManager}, * {@link org.springframework.cache.jcache.JCacheCacheManager},
* {@link org.springframework.cache.ehcache.EhCacheCacheManager}, * {@link org.springframework.cache.ehcache.EhCacheCacheManager},
* {@link com.github.benmanes.caffeine.cache.CaffeineCacheManager} or * {@link org.springframework.cache.caffeine.CaffeineCacheManager} or
* {@link org.springframework.cache.guava.GuavaCacheManager}. * {@link org.springframework.cache.guava.GuavaCacheManager}.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
...@@ -106,9 +106,7 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA ...@@ -106,9 +106,7 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA
if (allowNullValues != this.allowNullValues) { if (allowNullValues != this.allowNullValues) {
this.allowNullValues = allowNullValues; this.allowNullValues = allowNullValues;
// Need to recreate all Cache instances with the new null-value configuration... // Need to recreate all Cache instances with the new null-value configuration...
for (Map.Entry<String, Cache> entry : this.cacheMap.entrySet()) { recreateCaches();
entry.setValue(createConcurrentMapCache(entry.getKey()));
}
} }
} }
...@@ -127,14 +125,13 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA ...@@ -127,14 +125,13 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA
* contract is required on cached values. * contract is required on cached values.
* <p>Note: A change of the store-by-value setting will reset all existing caches, * <p>Note: A change of the store-by-value setting will reset all existing caches,
* if any, to reconfigure them with the new store-by-value requirement. * if any, to reconfigure them with the new store-by-value requirement.
* @since 4.3
*/ */
public void setStoreByValue(boolean storeByValue) { public void setStoreByValue(boolean storeByValue) {
if (storeByValue != this.storeByValue) { if (storeByValue != this.storeByValue) {
this.storeByValue = storeByValue; this.storeByValue = storeByValue;
// Need to recreate all Cache instances with the new store-by-value configuration... // Need to recreate all Cache instances with the new store-by-value configuration...
for (Map.Entry<String, Cache> entry : this.cacheMap.entrySet()) { recreateCaches();
entry.setValue(createConcurrentMapCache(entry.getKey()));
}
} }
} }
...@@ -142,6 +139,7 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA ...@@ -142,6 +139,7 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA
* Return whether this cache manager stores a copy of each entry or * Return whether this cache manager stores a copy of each entry or
* a reference for all its caches. If store by value is enabled, any * a reference for all its caches. If store by value is enabled, any
* cache entry must be serializable. * cache entry must be serializable.
* @since 4.3
*/ */
public boolean isStoreByValue() { public boolean isStoreByValue() {
return this.storeByValue; return this.storeByValue;
...@@ -150,8 +148,13 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA ...@@ -150,8 +148,13 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA
@Override @Override
public void setBeanClassLoader(ClassLoader classLoader) { public void setBeanClassLoader(ClassLoader classLoader) {
this.serialization = new SerializationDelegate(classLoader); this.serialization = new SerializationDelegate(classLoader);
// Need to recreate all Cache instances with new ClassLoader in store-by-value mode...
if (isStoreByValue()) {
recreateCaches();
}
} }
@Override @Override
public Collection<String> getCacheNames() { public Collection<String> getCacheNames() {
return Collections.unmodifiableSet(this.cacheMap.keySet()); return Collections.unmodifiableSet(this.cacheMap.keySet());
...@@ -172,14 +175,19 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA ...@@ -172,14 +175,19 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA
return cache; return cache;
} }
private void recreateCaches() {
for (Map.Entry<String, Cache> entry : this.cacheMap.entrySet()) {
entry.setValue(createConcurrentMapCache(entry.getKey()));
}
}
/** /**
* Create a new ConcurrentMapCache instance for the specified cache name. * Create a new ConcurrentMapCache instance for the specified cache name.
* @param name the name of the cache * @param name the name of the cache
* @return the ConcurrentMapCache (or a decorator thereof) * @return the ConcurrentMapCache (or a decorator thereof)
*/ */
protected Cache createConcurrentMapCache(String name) { protected Cache createConcurrentMapCache(String name) {
SerializationDelegate actualSerialization = SerializationDelegate actualSerialization = (isStoreByValue() ? this.serialization : null);
this.storeByValue ? this.serialization : null;
return new ConcurrentMapCache(name, new ConcurrentHashMap<Object, Object>(256), return new ConcurrentMapCache(name, new ConcurrentHashMap<Object, Object>(256),
isAllowNullValues(), actualSerialization); isAllowNullValues(), actualSerialization);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册