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:
@@ -269,8 +269,6 @@ project('spring-context') {
|
|||||||
}
|
}
|
||||||
compile("joda-time:joda-time:1.6", optional)
|
compile("joda-time:joda-time:1.6", optional)
|
||||||
compile("org.jruby:jruby:1.4.0", optional)
|
compile("org.jruby:jruby:1.4.0", optional)
|
||||||
compile("javax.cache:cache-api:0.5", optional)
|
|
||||||
compile("net.sf.ehcache:ehcache-core:2.0.0", optional)
|
|
||||||
compile("org.slf4j:slf4j-api:1.6.1", optional)
|
compile("org.slf4j:slf4j-api:1.6.1", optional)
|
||||||
compile("org.codehaus.jsr166-mirror:jsr166:1.7.0", provided)
|
compile("org.codehaus.jsr166-mirror:jsr166:1.7.0", provided)
|
||||||
compile("org.aspectj:aspectjweaver:${aspectjVersion}", optional)
|
compile("org.aspectj:aspectjweaver:${aspectjVersion}", optional)
|
||||||
@@ -361,6 +359,8 @@ project('spring-context-support') {
|
|||||||
compile(project(":spring-jdbc"), optional) // for Quartz support
|
compile(project(":spring-jdbc"), optional) // for Quartz support
|
||||||
compile(project(":spring-tx"), optional) // for Quartz support
|
compile(project(":spring-tx"), optional) // for Quartz support
|
||||||
compile("org.codehaus.fabric3.api:commonj:1.1.0", optional)
|
compile("org.codehaus.fabric3.api:commonj:1.1.0", optional)
|
||||||
|
compile("javax.cache:cache-api:0.5", optional)
|
||||||
|
compile("net.sf.ehcache:ehcache-core:2.0.0", optional)
|
||||||
compile("opensymphony:quartz:1.6.2", optional)
|
compile("opensymphony:quartz:1.6.2", optional)
|
||||||
compile("javax.mail:mail:1.4", optional)
|
compile("javax.mail:mail:1.4", optional)
|
||||||
compile("velocity:velocity:1.5", optional)
|
compile("velocity:velocity:1.5", optional)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import net.sf.ehcache.Ehcache;
|
|||||||
import net.sf.ehcache.Status;
|
import net.sf.ehcache.Status;
|
||||||
|
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.support.AbstractCacheManager;
|
import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,11 +33,27 @@ import org.springframework.util.Assert;
|
|||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public class EhCacheCacheManager extends AbstractCacheManager {
|
public class EhCacheCacheManager extends AbstractTransactionSupportingCacheManager {
|
||||||
|
|
||||||
private net.sf.ehcache.CacheManager cacheManager;
|
private net.sf.ehcache.CacheManager cacheManager;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new EhCacheCacheManager, setting the target EhCache CacheManager
|
||||||
|
* through the {@link #setCacheManager} bean property.
|
||||||
|
*/
|
||||||
|
public EhCacheCacheManager() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new EhCacheCacheManager for the given backing EhCache.
|
||||||
|
* @param cacheManager the backing EhCache {@link net.sf.ehcache.CacheManager}
|
||||||
|
*/
|
||||||
|
public EhCacheCacheManager(net.sf.ehcache.CacheManager cacheManager) {
|
||||||
|
this.cacheManager = cacheManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the backing EhCache {@link net.sf.ehcache.CacheManager}.
|
* Set the backing EhCache {@link net.sf.ehcache.CacheManager}.
|
||||||
*/
|
*/
|
||||||
@@ -18,11 +18,11 @@ package org.springframework.cache.jcache;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
import javax.cache.CacheManager;
|
||||||
import javax.cache.Status;
|
import javax.cache.Status;
|
||||||
|
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.support.AbstractCacheManager;
|
import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,13 +32,29 @@ import org.springframework.util.Assert;
|
|||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
public class JCacheCacheManager extends AbstractCacheManager {
|
public class JCacheCacheManager extends AbstractTransactionSupportingCacheManager {
|
||||||
|
|
||||||
private javax.cache.CacheManager cacheManager;
|
private javax.cache.CacheManager cacheManager;
|
||||||
|
|
||||||
private boolean allowNullValues = true;
|
private boolean allowNullValues = true;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new JCacheCacheManager, setting the target JCache CacheManager
|
||||||
|
* through the {@link #setCacheManager} bean property.
|
||||||
|
*/
|
||||||
|
public JCacheCacheManager() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new JCacheCacheManager for the given backing JCache.
|
||||||
|
* @param cacheManager the backing JCache {@link javax.cache.CacheManager}
|
||||||
|
*/
|
||||||
|
public JCacheCacheManager(CacheManager cacheManager) {
|
||||||
|
this.cacheManager = cacheManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the backing JCache {@link javax.cache.CacheManager}.
|
* Set the backing JCache {@link javax.cache.CacheManager}.
|
||||||
*/
|
*/
|
||||||
@@ -20,6 +20,7 @@ import javax.cache.CacheManager;
|
|||||||
import javax.cache.Caching;
|
import javax.cache.Caching;
|
||||||
|
|
||||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||||
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
@@ -33,7 +34,8 @@ import org.springframework.beans.factory.InitializingBean;
|
|||||||
* @see javax.cache.Caching#getCacheManager()
|
* @see javax.cache.Caching#getCacheManager()
|
||||||
* @see javax.cache.Caching#getCacheManager(String)
|
* @see javax.cache.Caching#getCacheManager(String)
|
||||||
*/
|
*/
|
||||||
public class JCacheManagerFactoryBean implements FactoryBean<CacheManager>, BeanClassLoaderAware, InitializingBean {
|
public class JCacheManagerFactoryBean
|
||||||
|
implements FactoryBean<CacheManager>, BeanClassLoaderAware, InitializingBean, DisposableBean {
|
||||||
|
|
||||||
private String cacheManagerName = Caching.DEFAULT_CACHE_MANAGER_NAME;
|
private String cacheManagerName = Caching.DEFAULT_CACHE_MANAGER_NAME;
|
||||||
|
|
||||||
@@ -74,4 +76,9 @@ public class JCacheManagerFactoryBean implements FactoryBean<CacheManager>, Bean
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
this.cacheManager.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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.transaction;
|
||||||
|
|
||||||
|
import org.springframework.cache.Cache;
|
||||||
|
import org.springframework.cache.support.AbstractCacheManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for CacheManager implementations that want to support built-in
|
||||||
|
* awareness of Spring-managed transactions. This usually needs to be switched
|
||||||
|
* on explicitly through the {@link #setTransactionAware} bean property.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 3.2
|
||||||
|
* @see #setTransactionAware
|
||||||
|
* @see TransactionAwareCacheDecorator
|
||||||
|
* @see TransactionAwareCacheManagerProxy
|
||||||
|
*/
|
||||||
|
public abstract class AbstractTransactionSupportingCacheManager extends AbstractCacheManager {
|
||||||
|
|
||||||
|
private boolean transactionAware = false;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether this CacheManager should expose transaction-aware Cache objects.
|
||||||
|
* <p>Default is "false". Set this to "true" to synchronize cache put/evict
|
||||||
|
* operations with ongoing Spring-managed transactions, performing the actual cache
|
||||||
|
* put/evict operation only in the after-commit phase of a successful transaction.
|
||||||
|
*/
|
||||||
|
public void setTransactionAware(boolean transactionAware) {
|
||||||
|
this.transactionAware = transactionAware;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether this CacheManager has been configured to be transaction-aware.
|
||||||
|
*/
|
||||||
|
public boolean isTransactionAware() {
|
||||||
|
return this.transactionAware;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Cache decorateCache(Cache cache) {
|
||||||
|
return (isTransactionAware() ? new TransactionAwareCacheDecorator(cache) : cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* 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.transaction;
|
||||||
|
|
||||||
|
import org.springframework.cache.Cache;
|
||||||
|
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
|
||||||
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache decorator which synchronizes its {@link #put} and {@link #evict} operations with
|
||||||
|
* Spring-managed transactions (through Spring's {@link TransactionSynchronizationManager},
|
||||||
|
* performing the actual cache put/evict operation only in the after-commit phase of a
|
||||||
|
* successful transaction. If no transaction is active, {@link #put} and {@link #evict}
|
||||||
|
* operations will be performed immediately, as usual.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 3.2
|
||||||
|
* @see TransactionAwareCacheManagerProxy
|
||||||
|
*/
|
||||||
|
public class TransactionAwareCacheDecorator implements Cache {
|
||||||
|
|
||||||
|
private final Cache targetCache;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new TransactionAwareCache for the given target Cache.
|
||||||
|
* @param targetCache the target Cache to decorate
|
||||||
|
*/
|
||||||
|
public TransactionAwareCacheDecorator(Cache targetCache) {
|
||||||
|
Assert.notNull(targetCache, "Target Cache must not be null");
|
||||||
|
this.targetCache = targetCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.targetCache.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getNativeCache() {
|
||||||
|
return this.targetCache.getNativeCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueWrapper get(Object key) {
|
||||||
|
return this.targetCache.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(final Object key, final Object value) {
|
||||||
|
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||||
|
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
|
||||||
|
@Override
|
||||||
|
public void afterCommit() {
|
||||||
|
targetCache.put(key, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.targetCache.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void evict(final Object key) {
|
||||||
|
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||||
|
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
|
||||||
|
@Override
|
||||||
|
public void afterCommit() {
|
||||||
|
targetCache.evict(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.targetCache.evict(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
this.targetCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* 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.transaction;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.cache.Cache;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy for a target {@link CacheManager}, exposing transaction-aware {@link Cache} objects
|
||||||
|
* which synchronize their {@link Cache#put} operations with Spring-managed transactions
|
||||||
|
* (through Spring's {@link org.springframework.transaction.support.TransactionSynchronizationManager},
|
||||||
|
* performing the actual cache put operation only in the after-commit phase of a successful transaction.
|
||||||
|
* If no transaction is active, {@link Cache#put} operations will be performed immediately, as usual.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 3.2
|
||||||
|
* @see #setTargetCacheManager
|
||||||
|
* @see TransactionAwareCacheDecorator
|
||||||
|
* @see org.springframework.transaction.support.TransactionSynchronizationManager
|
||||||
|
*/
|
||||||
|
public class TransactionAwareCacheManagerProxy implements CacheManager, InitializingBean {
|
||||||
|
|
||||||
|
private CacheManager targetCacheManager;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new TransactionAwareCacheManagerProxy, setting the target CacheManager
|
||||||
|
* through the {@link #setTargetCacheManager} bean property.
|
||||||
|
*/
|
||||||
|
public TransactionAwareCacheManagerProxy() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new TransactionAwareCacheManagerProxy for the given target CacheManager.
|
||||||
|
* @param targetCacheManager the target CacheManager to proxy
|
||||||
|
*/
|
||||||
|
public TransactionAwareCacheManagerProxy(CacheManager targetCacheManager) {
|
||||||
|
Assert.notNull(targetCacheManager, "Target CacheManager must not be null");
|
||||||
|
this.targetCacheManager = targetCacheManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the target CacheManager to proxy.
|
||||||
|
*/
|
||||||
|
public void setTargetCacheManager(CacheManager targetCacheManager) {
|
||||||
|
this.targetCacheManager = targetCacheManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void afterPropertiesSet() {
|
||||||
|
if (this.targetCacheManager == null) {
|
||||||
|
throw new IllegalStateException("'targetCacheManager' is required");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Cache getCache(String name) {
|
||||||
|
return new TransactionAwareCacheDecorator(this.targetCacheManager.getCache(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<String> getCacheNames() {
|
||||||
|
return this.targetCacheManager.getCacheNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
5
spring-context-support/src/main/java/org/springframework/cache/transaction/package-info.java
vendored
Normal file
5
spring-context-support/src/main/java/org/springframework/cache/transaction/package-info.java
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* Transaction-aware decorators for the the org.springframework.cache package.
|
||||||
|
* Provides synchronization of put operations with Spring-managed transactions.
|
||||||
|
*/
|
||||||
|
package org.springframework.cache.transaction;
|
||||||
@@ -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");
|
* 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.
|
||||||
@@ -14,38 +14,45 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.vendor;
|
package org.springframework.cache.ehcache;
|
||||||
|
|
||||||
|
import net.sf.ehcache.CacheManager;
|
||||||
|
import net.sf.ehcache.Ehcache;
|
||||||
|
import net.sf.ehcache.Element;
|
||||||
|
import net.sf.ehcache.config.CacheConfiguration;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.cache.Cache;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
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
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractNativeCacheTests<T> {
|
public class EhCacheCacheTests {
|
||||||
|
|
||||||
protected T nativeCache;
|
|
||||||
protected Cache cache;
|
|
||||||
protected final static String CACHE_NAME = "testCache";
|
protected final static String CACHE_NAME = "testCache";
|
||||||
|
|
||||||
|
protected Ehcache nativeCache;
|
||||||
|
|
||||||
|
protected Cache cache;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
nativeCache = createNativeCache();
|
if (CacheManager.getInstance().cacheExists(CACHE_NAME)) {
|
||||||
cache = createCache(nativeCache);
|
nativeCache = CacheManager.getInstance().getEhcache(CACHE_NAME);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nativeCache = new net.sf.ehcache.Cache(new CacheConfiguration(CACHE_NAME, 100));
|
||||||
|
CacheManager.getInstance().addCache(nativeCache);
|
||||||
|
}
|
||||||
|
cache = new EhCacheCache(nativeCache);
|
||||||
cache.clear();
|
cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected abstract T createNativeCache() throws Exception;
|
|
||||||
|
|
||||||
protected abstract Cache createCache(T nativeCache);
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCacheName() throws Exception {
|
public void testCacheName() throws Exception {
|
||||||
assertEquals(CACHE_NAME, cache.getName());
|
assertEquals(CACHE_NAME, cache.getName());
|
||||||
@@ -85,4 +92,20 @@ public abstract class AbstractNativeCacheTests<T> {
|
|||||||
assertNull(cache.get("vlaicu"));
|
assertNull(cache.get("vlaicu"));
|
||||||
assertNull(cache.get("enescu"));
|
assertNull(cache.get("enescu"));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
package org.springframework.cache.ehcache;
|
package org.springframework.cache.ehcache;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import net.sf.ehcache.Cache;
|
import net.sf.ehcache.Cache;
|
||||||
import net.sf.ehcache.CacheManager;
|
import net.sf.ehcache.CacheManager;
|
||||||
import net.sf.ehcache.Ehcache;
|
import net.sf.ehcache.Ehcache;
|
||||||
@@ -152,7 +151,7 @@ public class EhCacheSupportTests extends TestCase {
|
|||||||
assertTrue("overridden diskExpiryThreadIntervalSeconds is correct", config.getDiskExpiryThreadIntervalSeconds() == 10);
|
assertTrue("overridden diskExpiryThreadIntervalSeconds is correct", config.getDiskExpiryThreadIntervalSeconds() == 10);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if (useCacheManagerFb) {
|
if (useCacheManagerFb && cacheManagerFb != null) {
|
||||||
cacheManagerFb.destroy();
|
cacheManagerFb.destroy();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2012 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.
|
||||||
@@ -51,16 +51,27 @@ public abstract class AbstractCacheManager implements CacheManager, Initializing
|
|||||||
|
|
||||||
// preserve the initial order of the cache names
|
// preserve the initial order of the cache names
|
||||||
for (Cache cache : caches) {
|
for (Cache cache : caches) {
|
||||||
this.cacheMap.put(cache.getName(), cache);
|
this.cacheMap.put(cache.getName(), decorateCache(cache));
|
||||||
this.cacheNames.add(cache.getName());
|
this.cacheNames.add(cache.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void addCache(Cache cache) {
|
protected final void addCache(Cache cache) {
|
||||||
this.cacheMap.put(cache.getName(), cache);
|
this.cacheMap.put(cache.getName(), decorateCache(cache));
|
||||||
this.cacheNames.add(cache.getName());
|
this.cacheNames.add(cache.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorate the given Cache object if necessary.
|
||||||
|
* @param cache the Cache object to be added to this CacheManager
|
||||||
|
* @return the decorated Cache object to be used instead,
|
||||||
|
* or simply the passed-in Cache object by default
|
||||||
|
*/
|
||||||
|
protected Cache decorateCache(Cache cache) {
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Cache getCache(String name) {
|
public Cache getCache(String name) {
|
||||||
return this.cacheMap.get(name);
|
return this.cacheMap.get(name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* 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.
|
||||||
@@ -19,21 +19,71 @@ package org.springframework.cache.concurrent;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.vendor.AbstractNativeCacheTests;
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public class ConcurrentCacheTests extends AbstractNativeCacheTests<ConcurrentMap<Object, Object>> {
|
public class ConcurrentCacheTests {
|
||||||
|
|
||||||
@Override
|
protected final static String CACHE_NAME = "testCache";
|
||||||
protected Cache createCache(ConcurrentMap<Object, Object> nativeCache) {
|
|
||||||
return new ConcurrentMapCache(CACHE_NAME, nativeCache, true);
|
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 {
|
@Test
|
||||||
return new ConcurrentHashMap<Object, Object>();
|
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"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user