Added "transactionAware" bean property to EhCacheCacheManager and JCacheCacheManager

In the course of this enhancement, the "cache.ehcache" and "cache.jcache" packages moved from spring-context to the spring-context-support module, expecting further transaction-related functionality. Also aligns with the presence of Spring's Quartz support in the spring-context-support module, since Quartz and EHCache are sort of sister projects at Terracotta now.

Issue: SPR-9966
This commit is contained in:
Juergen Hoeller
2012-11-25 21:58:35 +01:00
parent 7d7758bfc9
commit e2f418ab4c
20 changed files with 406 additions and 103 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2010-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,21 +19,71 @@ package org.springframework.cache.concurrent;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.junit.Before;
import org.junit.Test;
import org.springframework.cache.Cache;
import org.springframework.cache.vendor.AbstractNativeCacheTests;
import static org.junit.Assert.*;
/**
* @author Costin Leau
*/
public class ConcurrentCacheTests extends AbstractNativeCacheTests<ConcurrentMap<Object, Object>> {
public class ConcurrentCacheTests {
@Override
protected Cache createCache(ConcurrentMap<Object, Object> nativeCache) {
return new ConcurrentMapCache(CACHE_NAME, nativeCache, true);
protected final static String CACHE_NAME = "testCache";
protected ConcurrentMap<Object, Object> nativeCache;
protected Cache cache;
@Before
public void setUp() throws Exception {
nativeCache = new ConcurrentHashMap<Object, Object>();
cache = new ConcurrentMapCache(CACHE_NAME, nativeCache, true);
cache.clear();
}
@Override
protected ConcurrentMap<Object, Object> createNativeCache() throws Exception {
return new ConcurrentHashMap<Object, Object>();
@Test
public void testCacheName() throws Exception {
assertEquals(CACHE_NAME, cache.getName());
}
@Test
public void testNativeCache() throws Exception {
assertSame(nativeCache, cache.getNativeCache());
}
@Test
public void testCachePut() throws Exception {
Object key = "enescu";
Object value = "george";
assertNull(cache.get(key));
cache.put(key, value);
assertEquals(value, cache.get(key).get());
}
@Test
public void testCacheRemove() throws Exception {
Object key = "enescu";
Object value = "george";
assertNull(cache.get(key));
cache.put(key, value);
}
@Test
public void testCacheClear() throws Exception {
assertNull(cache.get("enescu"));
cache.put("enescu", "george");
assertNull(cache.get("vlaicu"));
cache.put("vlaicu", "aurel");
cache.clear();
assertNull(cache.get("vlaicu"));
assertNull(cache.get("enescu"));
}
}

View File

@@ -1,62 +0,0 @@
/*
* Copyright 2010-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cache.ehcache;
import static org.junit.Assert.*;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import org.junit.Test;
import org.springframework.cache.Cache;
import org.springframework.cache.vendor.AbstractNativeCacheTests;
/**
* Integration test for EhCache cache.
*
* @author Costin Leau
*/
public class EhCacheCacheTests extends AbstractNativeCacheTests<Ehcache> {
@Override
protected Ehcache createNativeCache() throws Exception {
EhCacheFactoryBean fb = new EhCacheFactoryBean();
fb.setBeanName(CACHE_NAME);
fb.setCacheName(CACHE_NAME);
fb.afterPropertiesSet();
return fb.getObject();
}
@Override
protected Cache createCache(Ehcache nativeCache) {
return new EhCacheCache(nativeCache);
}
@Test
public void testExpiredElements() throws Exception {
String key = "brancusi";
String value = "constantin";
Element brancusi = new Element(key, value);
// ttl = 10s
brancusi.setTimeToLive(3);
nativeCache.put(brancusi);
assertEquals(value, cache.get(key).get());
// wait for the entry to expire
Thread.sleep(5 * 1000);
assertNull(cache.get(key));
}
}

View File

@@ -1,233 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cache.ehcache;
import junit.framework.TestCase;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
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 org.springframework.core.io.ClassPathResource;
/**
* @author Dmitriy Kopylenko
* @author Juergen Hoeller
* @since 27.09.2004
*/
public class EhCacheSupportTests extends TestCase {
public void testLoadingBlankCacheManager() throws Exception {
EhCacheManagerFactoryBean cacheManagerFb = new EhCacheManagerFactoryBean();
assertEquals(CacheManager.class, cacheManagerFb.getObjectType());
assertTrue("Singleton property", cacheManagerFb.isSingleton());
cacheManagerFb.afterPropertiesSet();
try {
CacheManager cm = cacheManagerFb.getObject();
assertTrue("Loaded CacheManager with no caches", cm.getCacheNames().length == 0);
Cache myCache1 = cm.getCache("myCache1");
assertTrue("No myCache1 defined", myCache1 == null);
}
finally {
cacheManagerFb.destroy();
}
}
public void testLoadingCacheManagerFromConfigFile() throws Exception {
EhCacheManagerFactoryBean cacheManagerFb = new EhCacheManagerFactoryBean();
cacheManagerFb.setConfigLocation(new ClassPathResource("testEhcache.xml", getClass()));
cacheManagerFb.setCacheManagerName("myCacheManager");
cacheManagerFb.afterPropertiesSet();
try {
CacheManager cm = cacheManagerFb.getObject();
assertTrue("Correct number of caches loaded", cm.getCacheNames().length == 1);
Cache myCache1 = cm.getCache("myCache1");
assertFalse("myCache1 is not eternal", myCache1.getCacheConfiguration().isEternal());
assertTrue("myCache1.maxElements == 300", myCache1.getCacheConfiguration().getMaxElementsInMemory() == 300);
}
finally {
cacheManagerFb.destroy();
}
}
public void testEhCacheFactoryBeanWithDefaultCacheManager() throws Exception {
doTestEhCacheFactoryBean(false);
}
public void testEhCacheFactoryBeanWithExplicitCacheManager() throws Exception {
doTestEhCacheFactoryBean(true);
}
private void doTestEhCacheFactoryBean(boolean useCacheManagerFb) throws Exception {
Cache cache = null;
EhCacheManagerFactoryBean cacheManagerFb = null;
try {
EhCacheFactoryBean cacheFb = new EhCacheFactoryBean();
Class<? extends Ehcache> objectType = cacheFb.getObjectType();
assertTrue(Ehcache.class.isAssignableFrom(objectType));
assertTrue("Singleton property", cacheFb.isSingleton());
if (useCacheManagerFb) {
cacheManagerFb = new EhCacheManagerFactoryBean();
cacheManagerFb.setConfigLocation(new ClassPathResource("testEhcache.xml", getClass()));
cacheManagerFb.afterPropertiesSet();
cacheFb.setCacheManager(cacheManagerFb.getObject());
}
cacheFb.setCacheName("myCache1");
cacheFb.afterPropertiesSet();
cache = (Cache) cacheFb.getObject();
Class<? extends Ehcache> objectType2 = cacheFb.getObjectType();
assertSame(objectType, objectType2);
CacheConfiguration config = cache.getCacheConfiguration();
assertEquals("myCache1", cache.getName());
if (useCacheManagerFb){
assertEquals("myCache1.maxElements", 300, config.getMaxElementsInMemory());
}
else {
assertEquals("myCache1.maxElements", 10000, config.getMaxElementsInMemory());
}
// Cache region is not defined. Should create one with default properties.
cacheFb = new EhCacheFactoryBean();
if (useCacheManagerFb) {
cacheFb.setCacheManager(cacheManagerFb.getObject());
}
cacheFb.setCacheName("undefinedCache");
cacheFb.afterPropertiesSet();
cache = (Cache) cacheFb.getObject();
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
cacheFb = new EhCacheFactoryBean();
if (useCacheManagerFb) {
cacheFb.setCacheManager(cacheManagerFb.getObject());
}
cacheFb.setBeanName("undefinedCache2");
cacheFb.setMaxElementsInMemory(5);
cacheFb.setOverflowToDisk(false);
cacheFb.setEternal(true);
cacheFb.setTimeToLive(8);
cacheFb.setTimeToIdle(7);
cacheFb.setDiskPersistent(true);
cacheFb.setDiskExpiryThreadIntervalSeconds(10);
cacheFb.afterPropertiesSet();
cache = (Cache) cacheFb.getObject();
config = cache.getCacheConfiguration();
assertEquals("undefinedCache2", cache.getName());
assertTrue("overridden maxElements is correct", config.getMaxElementsInMemory() == 5);
assertFalse("overridden overflowToDisk is correct", config.isOverflowToDisk());
assertTrue("overridden eternal is correct", config.isEternal());
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 {
if (useCacheManagerFb) {
cacheManagerFb.destroy();
}
else {
CacheManager.getInstance().shutdown();
}
}
}
public void testEhCacheFactoryBeanWithBlockingCache() throws Exception {
EhCacheManagerFactoryBean cacheManagerFb = new EhCacheManagerFactoryBean();
cacheManagerFb.afterPropertiesSet();
try {
CacheManager cm = cacheManagerFb.getObject();
EhCacheFactoryBean cacheFb = new EhCacheFactoryBean();
cacheFb.setCacheManager(cm);
cacheFb.setCacheName("myCache1");
cacheFb.setBlocking(true);
assertEquals(cacheFb.getObjectType(), BlockingCache.class);
cacheFb.afterPropertiesSet();
Ehcache myCache1 = cm.getEhcache("myCache1");
assertTrue(myCache1 instanceof BlockingCache);
}
finally {
cacheManagerFb.destroy();
}
}
public void testEhCacheFactoryBeanWithSelfPopulatingCache() throws Exception {
EhCacheManagerFactoryBean cacheManagerFb = new EhCacheManagerFactoryBean();
cacheManagerFb.afterPropertiesSet();
try {
CacheManager cm = cacheManagerFb.getObject();
EhCacheFactoryBean cacheFb = new EhCacheFactoryBean();
cacheFb.setCacheManager(cm);
cacheFb.setCacheName("myCache1");
cacheFb.setCacheEntryFactory(new CacheEntryFactory() {
public Object createEntry(Object key) throws Exception {
return key;
}
});
assertEquals(cacheFb.getObjectType(), SelfPopulatingCache.class);
cacheFb.afterPropertiesSet();
Ehcache myCache1 = cm.getEhcache("myCache1");
assertTrue(myCache1 instanceof SelfPopulatingCache);
assertEquals("myKey1", myCache1.get("myKey1").getValue());
}
finally {
cacheManagerFb.destroy();
}
}
public void testEhCacheFactoryBeanWithUpdatingSelfPopulatingCache() throws Exception {
EhCacheManagerFactoryBean cacheManagerFb = new EhCacheManagerFactoryBean();
cacheManagerFb.afterPropertiesSet();
try {
CacheManager cm = cacheManagerFb.getObject();
EhCacheFactoryBean cacheFb = new EhCacheFactoryBean();
cacheFb.setCacheManager(cm);
cacheFb.setCacheName("myCache1");
cacheFb.setCacheEntryFactory(new UpdatingCacheEntryFactory() {
public Object createEntry(Object key) throws Exception {
return key;
}
public void updateEntryValue(Object key, Object value) throws Exception {
}
});
assertEquals(cacheFb.getObjectType(), UpdatingSelfPopulatingCache.class);
cacheFb.afterPropertiesSet();
Ehcache myCache1 = cm.getEhcache("myCache1");
assertTrue(myCache1 instanceof UpdatingSelfPopulatingCache);
assertEquals("myKey1", myCache1.get("myKey1").getValue());
}
finally {
cacheManagerFb.destroy();
}
}
}

View File

@@ -1,88 +0,0 @@
/*
* Copyright 2010-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cache.vendor;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.cache.Cache;
/**
* Test for native cache implementations.
*
* @author Costin Leau
*/
public abstract class AbstractNativeCacheTests<T> {
protected T nativeCache;
protected Cache cache;
protected final static String CACHE_NAME = "testCache";
@Before
public void setUp() throws Exception {
nativeCache = createNativeCache();
cache = createCache(nativeCache);
cache.clear();
}
protected abstract T createNativeCache() throws Exception;
protected abstract Cache createCache(T nativeCache);
@Test
public void testCacheName() throws Exception {
assertEquals(CACHE_NAME, cache.getName());
}
@Test
public void testNativeCache() throws Exception {
assertSame(nativeCache, cache.getNativeCache());
}
@Test
public void testCachePut() throws Exception {
Object key = "enescu";
Object value = "george";
assertNull(cache.get(key));
cache.put(key, value);
assertEquals(value, cache.get(key).get());
}
@Test
public void testCacheRemove() throws Exception {
Object key = "enescu";
Object value = "george";
assertNull(cache.get(key));
cache.put(key, value);
}
@Test
public void testCacheClear() throws Exception {
assertNull(cache.get("enescu"));
cache.put("enescu", "george");
assertNull(cache.get("vlaicu"));
cache.put("vlaicu", "aurel");
cache.clear();
assertNull(cache.get("vlaicu"));
assertNull(cache.get("enescu"));
}
}

View File

@@ -1,50 +0,0 @@
<ehcache>
<!-- Sets the path to the directory where cache .data files are created.
If the path is a Java System Property it is replaced by
its value in the running VM.
The following properties are translated:
user.home - User's home directory
user.dir - User's current working directory
java.io.tmpdir - Default temp file path -->
<diskStore path="java.io.tmpdir"/>
<!--Default Cache configuration. These will applied to caches programmatically created through
the CacheManager.
The following attributes are required for defaultCache:
maxInMemory - Sets the maximum number of objects that will be created in memory
eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element
is never expired.
timeToIdleSeconds - Sets the time to idle for an element before it expires.
i.e. The maximum amount of time between accesses before an element expires
Is only used if the element is not eternal.
Optional attribute. A value of 0 means that an Element can idle for infinity
timeToLiveSeconds - Sets the time to live for an element before it expires.
i.e. The maximum time between creation time and when an element expires.
Is only used if the element is not eternal.
overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit.
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
<cache name="myCache1"
maxElementsInMemory="300"
eternal="false"
timeToIdleSeconds="500"
timeToLiveSeconds="500"
overflowToDisk="true"
/>
</ehcache>