diff --git a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java index dcec4047eee..435e780e938 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java +++ b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java @@ -24,20 +24,19 @@ import net.sf.ehcache.CacheException; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Ehcache; import net.sf.ehcache.bootstrap.BootstrapCacheLoader; +import net.sf.ehcache.config.CacheConfiguration; import net.sf.ehcache.constructs.blocking.BlockingCache; import net.sf.ehcache.constructs.blocking.CacheEntryFactory; import net.sf.ehcache.constructs.blocking.SelfPopulatingCache; import net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory; import net.sf.ehcache.constructs.blocking.UpdatingSelfPopulatingCache; import net.sf.ehcache.event.CacheEventListener; -import net.sf.ehcache.store.MemoryStoreEvictionPolicy; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; /** * {@link FactoryBean} that creates a named EhCache {@link net.sf.ehcache.Cache} instance @@ -52,8 +51,7 @@ import org.springframework.util.Assert; *

Note: If the named Cache instance is found, the properties will be ignored and the * Cache instance will be retrieved from the CacheManager. * - *

Note: As of Spring 3.0, Spring's EhCache support requires EhCache 1.3 or higher. - * As of Spring 3.2, we recommend using EhCache 2.1 or higher. + *

Note: As of Spring 4.0, Spring's EhCache support requires EhCache 2.1 or higher. * @author Dmitriy Kopylenko * @author Juergen Hoeller @@ -62,36 +60,12 @@ import org.springframework.util.Assert; * @see EhCacheManagerFactoryBean * @see net.sf.ehcache.Cache */ -public class EhCacheFactoryBean implements FactoryBean, BeanNameAware, InitializingBean { +public class EhCacheFactoryBean extends CacheConfiguration implements FactoryBean, BeanNameAware, InitializingBean { protected final Log logger = LogFactory.getLog(getClass()); private CacheManager cacheManager; - private String cacheName; - - private int maxElementsInMemory = 10000; - - private int maxElementsOnDisk = 10000000; - - private MemoryStoreEvictionPolicy memoryStoreEvictionPolicy = MemoryStoreEvictionPolicy.LRU; - - private boolean overflowToDisk = true; - - private boolean eternal = false; - - private int timeToLive = 120; - - private int timeToIdle = 120; - - private boolean diskPersistent = false; - - private int diskExpiryThreadIntervalSeconds = 120; - - private int diskSpoolBufferSize = 0; - - private boolean clearOnFlush = true; - private boolean blocking = false; private CacheEntryFactory cacheEntryFactory; @@ -111,6 +85,13 @@ public class EhCacheFactoryBean implements FactoryBean, BeanNameAware, private Ehcache cache; + public EhCacheFactoryBean() { + setMaxElementsInMemory(10000); + setMaxElementsOnDisk(10000000); + setTimeToLiveSeconds(120); + setTimeToIdleSeconds(120); + } + /** * Set a CacheManager from which to retrieve a named Cache instance. * By default, {@code CacheManager.getInstance()} will be called. @@ -131,100 +112,28 @@ public class EhCacheFactoryBean implements FactoryBean, BeanNameAware, * Default is the bean name of this EhCacheFactoryBean. */ public void setCacheName(String cacheName) { - this.cacheName = cacheName; - } - - /** - * Specify the maximum number of cached objects in memory. - * Default is 10000 elements. - */ - public void setMaxElementsInMemory(int maxElementsInMemory) { - this.maxElementsInMemory = maxElementsInMemory; - } - - /** - * Specify the maximum number of cached objects on disk. - * Default is 10000000 elements. - */ - public void setMaxElementsOnDisk(int maxElementsOnDisk) { - this.maxElementsOnDisk = maxElementsOnDisk; - } - - /** - * Set the memory style eviction policy for this cache. - *

Supported values are "LRU", "LFU" and "FIFO", according to the - * constants defined in EhCache's MemoryStoreEvictionPolicy class. - * Default is "LRU". - */ - public void setMemoryStoreEvictionPolicy(MemoryStoreEvictionPolicy memoryStoreEvictionPolicy) { - Assert.notNull(memoryStoreEvictionPolicy, "memoryStoreEvictionPolicy must not be null"); - this.memoryStoreEvictionPolicy = memoryStoreEvictionPolicy; + setName(cacheName); } /** - * Set whether elements can overflow to disk when the in-memory cache - * has reached the maximum size limit. Default is "true". - */ - public void setOverflowToDisk(boolean overflowToDisk) { - this.overflowToDisk = overflowToDisk; - } - - /** - * Set whether elements are considered as eternal. If "true", timeouts - * are ignored and the element is never expired. Default is "false". - */ - public void setEternal(boolean eternal) { - this.eternal = eternal; - } - - /** - * Set the time in seconds to live for an element before it expires, - * i.e. the maximum time between creation time and when an element expires. - *

This is only used if the element is not eternal. Default is 120 seconds. + * @see #setTimeToLiveSeconds(long) */ public void setTimeToLive(int timeToLive) { - this.timeToLive = timeToLive; + setTimeToLiveSeconds(timeToLive); } /** - * Set the time in seconds to idle for an element before it expires, that is, - * the maximum amount of time between accesses before an element expires. - *

This is only used if the element is not eternal. Default is 120 seconds. + * @see #setTimeToIdleSeconds(long) */ public void setTimeToIdle(int timeToIdle) { - this.timeToIdle = timeToIdle; - } - - /** - * Set whether the disk store persists between restarts of the Virtual Machine. - * Default is "false". - */ - public void setDiskPersistent(boolean diskPersistent) { - this.diskPersistent = diskPersistent; - } - - /** - * Set the number of seconds between runs of the disk expiry thread. - * Default is 120 seconds. - */ - public void setDiskExpiryThreadIntervalSeconds(int diskExpiryThreadIntervalSeconds) { - this.diskExpiryThreadIntervalSeconds = diskExpiryThreadIntervalSeconds; + setTimeToIdleSeconds(timeToIdle); } /** - * Set the amount of memory to allocate the write buffer for puts to the disk store. - * Default is 0. + * @see #setDiskSpoolBufferSizeMB(int) */ public void setDiskSpoolBufferSize(int diskSpoolBufferSize) { - this.diskSpoolBufferSize = diskSpoolBufferSize; - } - - /** - * Set whether the memory store should be cleared when flush is called on the cache. - * Default is "true". - */ - public void setClearOnFlush(boolean clearOnFlush) { - this.clearOnFlush = clearOnFlush; + setDiskSpoolBufferSizeMB(diskSpoolBufferSize); } /** @@ -303,33 +212,35 @@ public class EhCacheFactoryBean implements FactoryBean, BeanNameAware, public void afterPropertiesSet() throws CacheException, IOException { + // If no cache name given, use bean name as cache name. + String cacheName = getName(); + if (cacheName == null) { + cacheName = this.beanName; + setName(cacheName); + } + // If no CacheManager given, fetch the default. if (this.cacheManager == null) { if (logger.isDebugEnabled()) { - logger.debug("Using default EhCache CacheManager for cache region '" + this.cacheName + "'"); + logger.debug("Using default EhCache CacheManager for cache region '" + cacheName + "'"); } this.cacheManager = CacheManager.getInstance(); } - // If no cache name given, use bean name as cache name. - if (this.cacheName == null) { - this.cacheName = this.beanName; - } - - // Fetch cache region: If none with the given name exists, - // create one on the fly. + // Fetch cache region: If none with the given name exists, create one on the fly. Ehcache rawCache; - if (this.cacheManager.cacheExists(this.cacheName)) { + if (this.cacheManager.cacheExists(cacheName)) { if (logger.isDebugEnabled()) { - logger.debug("Using existing EhCache cache region '" + this.cacheName + "'"); + logger.debug("Using existing EhCache cache region '" + cacheName + "'"); } - rawCache = this.cacheManager.getEhcache(this.cacheName); + rawCache = this.cacheManager.getEhcache(cacheName); } else { if (logger.isDebugEnabled()) { - logger.debug("Creating new EhCache cache region '" + this.cacheName + "'"); + logger.debug("Creating new EhCache cache region '" + cacheName + "'"); } rawCache = createCache(); + rawCache.setBootstrapCacheLoader(this.bootstrapCacheLoader); this.cacheManager.addCache(rawCache); } @@ -360,17 +271,7 @@ public class EhCacheFactoryBean implements FactoryBean, BeanNameAware, * Create a raw Cache object based on the configuration of this FactoryBean. */ protected Cache createCache() { - // Only call EhCache 1.6 constructor if actually necessary (for compatibility with EhCache 1.3+) - return (!this.clearOnFlush) ? - new Cache(this.cacheName, this.maxElementsInMemory, this.memoryStoreEvictionPolicy, - this.overflowToDisk, null, this.eternal, this.timeToLive, this.timeToIdle, - this.diskPersistent, this.diskExpiryThreadIntervalSeconds, null, - this.bootstrapCacheLoader, this.maxElementsOnDisk, this.diskSpoolBufferSize, - this.clearOnFlush) : - new Cache(this.cacheName, this.maxElementsInMemory, this.memoryStoreEvictionPolicy, - this.overflowToDisk, null, this.eternal, this.timeToLive, this.timeToIdle, - this.diskPersistent, this.diskExpiryThreadIntervalSeconds, null, - this.bootstrapCacheLoader, this.maxElementsOnDisk, this.diskSpoolBufferSize); + return new Cache(this); } /** diff --git a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java index a94c1fe2cb1..ea134b57aa7 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java +++ b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java @@ -18,7 +18,6 @@ package org.springframework.cache.ehcache; import java.io.IOException; import java.io.InputStream; -import java.lang.reflect.Method; import net.sf.ehcache.CacheException; import net.sf.ehcache.CacheManager; @@ -31,8 +30,6 @@ import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.core.io.Resource; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; /** * {@link FactoryBean} that exposes an EhCache {@link net.sf.ehcache.CacheManager} @@ -47,8 +44,7 @@ import org.springframework.util.ReflectionUtils; * and cares for proper shutdown of the CacheManager. EhCacheManagerFactoryBean is * also necessary for loading EhCache configuration from a non-default config location. * - *

Note: As of Spring 3.0, Spring's EhCache support requires EhCache 1.3 or higher. - * As of Spring 3.2, we recommend using EhCache 2.1 or higher. + *

Note: As of Spring 4.0, Spring's EhCache support requires EhCache 2.1 or higher. * * @author Dmitriy Kopylenko * @author Juergen Hoeller @@ -60,10 +56,6 @@ import org.springframework.util.ReflectionUtils; */ public class EhCacheManagerFactoryBean implements FactoryBean, InitializingBean, DisposableBean { - // Check whether EhCache 2.1+ CacheManager.create(Configuration) method is available... - private static final Method createWithConfiguration = - ClassUtils.getMethodIfAvailable(CacheManager.class, "create", Configuration.class); - protected final Log logger = LogFactory.getLog(getClass()); private Resource configLocation; @@ -110,34 +102,12 @@ public class EhCacheManagerFactoryBean implements FactoryBean, Ini logger.info("Initializing EhCache CacheManager"); InputStream is = (this.configLocation != null ? this.configLocation.getInputStream() : null); try { - // A bit convoluted for EhCache 1.x/2.0 compatibility. - // To be much simpler once we require EhCache 2.1+ + Configuration configuration = (is != null ? + ConfigurationFactory.parseConfiguration(is) : ConfigurationFactory.parseConfiguration()); if (this.cacheManagerName != null) { - if (this.shared && createWithConfiguration == null) { - // No CacheManager.create(Configuration) method available before EhCache 2.1; - // can only set CacheManager name after creation. - this.cacheManager = (is != null ? CacheManager.create(is) : CacheManager.create()); - this.cacheManager.setName(this.cacheManagerName); - } - else { - Configuration configuration = (is != null ? ConfigurationFactory.parseConfiguration(is) : - ConfigurationFactory.parseConfiguration()); - configuration.setName(this.cacheManagerName); - if (this.shared) { - this.cacheManager = (CacheManager) ReflectionUtils.invokeMethod(createWithConfiguration, null, configuration); - } - else { - this.cacheManager = new CacheManager(configuration); - } - } - } - // For strict backwards compatibility: use simplest possible constructors... - else if (this.shared) { - this.cacheManager = (is != null ? CacheManager.create(is) : CacheManager.create()); - } - else { - this.cacheManager = (is != null ? new CacheManager(is) : new CacheManager()); + configuration.setName(this.cacheManagerName); } + this.cacheManager = (this.shared ? CacheManager.create(configuration) : new CacheManager(configuration)); } finally { if (is != null) { diff --git a/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java b/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java index 6e8efcd8165..492a0f868e0 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java @@ -79,7 +79,7 @@ public class EhCacheSupportTests extends TestCase { } private void doTestEhCacheFactoryBean(boolean useCacheManagerFb) throws Exception { - Cache cache = null; + Cache cache; EhCacheManagerFactoryBean cacheManagerFb = null; try { EhCacheFactoryBean cacheFb = new EhCacheFactoryBean(); @@ -118,11 +118,9 @@ public class EhCacheSupportTests extends TestCase { config = cache.getCacheConfiguration(); assertEquals("undefinedCache", cache.getName()); assertTrue("default maxElements is correct", config.getMaxElementsInMemory() == 10000); - assertTrue("default overflowToDisk is correct", config.isOverflowToDisk()); assertFalse("default eternal is correct", config.isEternal()); assertTrue("default timeToLive is correct", config.getTimeToLiveSeconds() == 120); assertTrue("default timeToIdle is correct", config.getTimeToIdleSeconds() == 120); - assertTrue("default diskPersistent is correct", !config.isDiskPersistent()); assertTrue("default diskExpiryThreadIntervalSeconds is correct", config.getDiskExpiryThreadIntervalSeconds() == 120); // overriding the default properties @@ -132,10 +130,8 @@ public class EhCacheSupportTests extends TestCase { } cacheFb.setBeanName("undefinedCache2"); cacheFb.setMaxElementsInMemory(5); - cacheFb.setOverflowToDisk(false); cacheFb.setTimeToLive(8); cacheFb.setTimeToIdle(7); - cacheFb.setDiskPersistent(true); cacheFb.setDiskExpiryThreadIntervalSeconds(10); cacheFb.afterPropertiesSet(); cache = (Cache) cacheFb.getObject(); @@ -143,10 +139,8 @@ public class EhCacheSupportTests extends TestCase { assertEquals("undefinedCache2", cache.getName()); assertTrue("overridden maxElements is correct", config.getMaxElementsInMemory() == 5); - assertFalse("overridden overflowToDisk is correct", config.isOverflowToDisk()); assertTrue("default timeToLive is correct", config.getTimeToLiveSeconds() == 8); assertTrue("default timeToIdle is correct", config.getTimeToIdleSeconds() == 7); - assertTrue("overridden diskPersistent is correct", config.isDiskPersistent()); assertTrue("overridden diskExpiryThreadIntervalSeconds is correct", config.getDiskExpiryThreadIntervalSeconds() == 10); } finally {