Skip to content

Commit e2f418a

Browse files
committed
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
1 parent 7d7758b commit e2f418a

File tree

20 files changed

+404
-101
lines changed

20 files changed

+404
-101
lines changed

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,6 @@ project('spring-context') {
269269
}
270270
compile("joda-time:joda-time:1.6", optional)
271271
compile("org.jruby:jruby:1.4.0", optional)
272-
compile("javax.cache:cache-api:0.5", optional)
273-
compile("net.sf.ehcache:ehcache-core:2.0.0", optional)
274272
compile("org.slf4j:slf4j-api:1.6.1", optional)
275273
compile("org.codehaus.jsr166-mirror:jsr166:1.7.0", provided)
276274
compile("org.aspectj:aspectjweaver:${aspectjVersion}", optional)
@@ -361,6 +359,8 @@ project('spring-context-support') {
361359
compile(project(":spring-jdbc"), optional) // for Quartz support
362360
compile(project(":spring-tx"), optional) // for Quartz support
363361
compile("org.codehaus.fabric3.api:commonj:1.1.0", optional)
362+
compile("javax.cache:cache-api:0.5", optional)
363+
compile("net.sf.ehcache:ehcache-core:2.0.0", optional)
364364
compile("opensymphony:quartz:1.6.2", optional)
365365
compile("javax.mail:mail:1.4", optional)
366366
compile("velocity:velocity:1.5", optional)

spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java renamed to spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import net.sf.ehcache.Status;
2424

2525
import org.springframework.cache.Cache;
26-
import org.springframework.cache.support.AbstractCacheManager;
26+
import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager;
2727
import org.springframework.util.Assert;
2828

2929
/**
@@ -33,11 +33,27 @@
3333
* @author Juergen Hoeller
3434
* @since 3.1
3535
*/
36-
public class EhCacheCacheManager extends AbstractCacheManager {
36+
public class EhCacheCacheManager extends AbstractTransactionSupportingCacheManager {
3737

3838
private net.sf.ehcache.CacheManager cacheManager;
3939

4040

41+
/**
42+
* Create a new EhCacheCacheManager, setting the target EhCache CacheManager
43+
* through the {@link #setCacheManager} bean property.
44+
*/
45+
public EhCacheCacheManager() {
46+
}
47+
48+
/**
49+
* Create a new EhCacheCacheManager for the given backing EhCache.
50+
* @param cacheManager the backing EhCache {@link net.sf.ehcache.CacheManager}
51+
*/
52+
public EhCacheCacheManager(net.sf.ehcache.CacheManager cacheManager) {
53+
this.cacheManager = cacheManager;
54+
}
55+
56+
4157
/**
4258
* Set the backing EhCache {@link net.sf.ehcache.CacheManager}.
4359
*/

spring-context/src/main/java/org/springframework/cache/jcache/JCacheCacheManager.java renamed to spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCacheManager.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818

1919
import java.util.Collection;
2020
import java.util.LinkedHashSet;
21-
21+
import javax.cache.CacheManager;
2222
import javax.cache.Status;
2323

2424
import org.springframework.cache.Cache;
25-
import org.springframework.cache.support.AbstractCacheManager;
25+
import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager;
2626
import org.springframework.util.Assert;
2727

2828
/**
@@ -32,13 +32,29 @@
3232
* @author Juergen Hoeller
3333
* @since 3.2
3434
*/
35-
public class JCacheCacheManager extends AbstractCacheManager {
35+
public class JCacheCacheManager extends AbstractTransactionSupportingCacheManager {
3636

3737
private javax.cache.CacheManager cacheManager;
3838

3939
private boolean allowNullValues = true;
4040

4141

42+
/**
43+
* Create a new JCacheCacheManager, setting the target JCache CacheManager
44+
* through the {@link #setCacheManager} bean property.
45+
*/
46+
public JCacheCacheManager() {
47+
}
48+
49+
/**
50+
* Create a new JCacheCacheManager for the given backing JCache.
51+
* @param cacheManager the backing JCache {@link javax.cache.CacheManager}
52+
*/
53+
public JCacheCacheManager(CacheManager cacheManager) {
54+
this.cacheManager = cacheManager;
55+
}
56+
57+
4258
/**
4359
* Set the backing JCache {@link javax.cache.CacheManager}.
4460
*/

spring-context/src/main/java/org/springframework/cache/jcache/JCacheManagerFactoryBean.java renamed to spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheManagerFactoryBean.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import javax.cache.Caching;
2121

2222
import org.springframework.beans.factory.BeanClassLoaderAware;
23+
import org.springframework.beans.factory.DisposableBean;
2324
import org.springframework.beans.factory.FactoryBean;
2425
import org.springframework.beans.factory.InitializingBean;
2526

@@ -33,7 +34,8 @@
3334
* @see javax.cache.Caching#getCacheManager()
3435
* @see javax.cache.Caching#getCacheManager(String)
3536
*/
36-
public class JCacheManagerFactoryBean implements FactoryBean<CacheManager>, BeanClassLoaderAware, InitializingBean {
37+
public class JCacheManagerFactoryBean
38+
implements FactoryBean<CacheManager>, BeanClassLoaderAware, InitializingBean, DisposableBean {
3739

3840
private String cacheManagerName = Caching.DEFAULT_CACHE_MANAGER_NAME;
3941

@@ -74,4 +76,9 @@ public boolean isSingleton() {
7476
return true;
7577
}
7678

79+
80+
public void destroy() {
81+
this.cacheManager.shutdown();
82+
}
83+
7784
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2002-2012 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cache.transaction;
18+
19+
import org.springframework.cache.Cache;
20+
import org.springframework.cache.support.AbstractCacheManager;
21+
22+
/**
23+
* Base class for CacheManager implementations that want to support built-in
24+
* awareness of Spring-managed transactions. This usually needs to be switched
25+
* on explicitly through the {@link #setTransactionAware} bean property.
26+
*
27+
* @author Juergen Hoeller
28+
* @since 3.2
29+
* @see #setTransactionAware
30+
* @see TransactionAwareCacheDecorator
31+
* @see TransactionAwareCacheManagerProxy
32+
*/
33+
public abstract class AbstractTransactionSupportingCacheManager extends AbstractCacheManager {
34+
35+
private boolean transactionAware = false;
36+
37+
38+
/**
39+
* Set whether this CacheManager should expose transaction-aware Cache objects.
40+
* <p>Default is "false". Set this to "true" to synchronize cache put/evict
41+
* operations with ongoing Spring-managed transactions, performing the actual cache
42+
* put/evict operation only in the after-commit phase of a successful transaction.
43+
*/
44+
public void setTransactionAware(boolean transactionAware) {
45+
this.transactionAware = transactionAware;
46+
}
47+
48+
/**
49+
* Return whether this CacheManager has been configured to be transaction-aware.
50+
*/
51+
public boolean isTransactionAware() {
52+
return this.transactionAware;
53+
}
54+
55+
56+
@Override
57+
protected Cache decorateCache(Cache cache) {
58+
return (isTransactionAware() ? new TransactionAwareCacheDecorator(cache) : cache);
59+
}
60+
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright 2002-2012 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cache.transaction;
18+
19+
import org.springframework.cache.Cache;
20+
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
21+
import org.springframework.transaction.support.TransactionSynchronizationManager;
22+
import org.springframework.util.Assert;
23+
24+
/**
25+
* Cache decorator which synchronizes its {@link #put} and {@link #evict} operations with
26+
* Spring-managed transactions (through Spring's {@link TransactionSynchronizationManager},
27+
* performing the actual cache put/evict operation only in the after-commit phase of a
28+
* successful transaction. If no transaction is active, {@link #put} and {@link #evict}
29+
* operations will be performed immediately, as usual.
30+
*
31+
* @author Juergen Hoeller
32+
* @since 3.2
33+
* @see TransactionAwareCacheManagerProxy
34+
*/
35+
public class TransactionAwareCacheDecorator implements Cache {
36+
37+
private final Cache targetCache;
38+
39+
40+
/**
41+
* Create a new TransactionAwareCache for the given target Cache.
42+
* @param targetCache the target Cache to decorate
43+
*/
44+
public TransactionAwareCacheDecorator(Cache targetCache) {
45+
Assert.notNull(targetCache, "Target Cache must not be null");
46+
this.targetCache = targetCache;
47+
}
48+
49+
50+
public String getName() {
51+
return this.targetCache.getName();
52+
}
53+
54+
public Object getNativeCache() {
55+
return this.targetCache.getNativeCache();
56+
}
57+
58+
public ValueWrapper get(Object key) {
59+
return this.targetCache.get(key);
60+
}
61+
62+
public void put(final Object key, final Object value) {
63+
if (TransactionSynchronizationManager.isSynchronizationActive()) {
64+
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
65+
@Override
66+
public void afterCommit() {
67+
targetCache.put(key, value);
68+
}
69+
});
70+
}
71+
else {
72+
this.targetCache.put(key, value);
73+
}
74+
}
75+
76+
public void evict(final Object key) {
77+
if (TransactionSynchronizationManager.isSynchronizationActive()) {
78+
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
79+
@Override
80+
public void afterCommit() {
81+
targetCache.evict(key);
82+
}
83+
});
84+
}
85+
else {
86+
this.targetCache.evict(key);
87+
}
88+
}
89+
90+
public void clear() {
91+
this.targetCache.clear();
92+
}
93+
94+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2002-2012 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cache.transaction;
18+
19+
import java.util.Collection;
20+
21+
import org.springframework.beans.factory.InitializingBean;
22+
import org.springframework.cache.Cache;
23+
import org.springframework.cache.CacheManager;
24+
import org.springframework.util.Assert;
25+
26+
/**
27+
* Proxy for a target {@link CacheManager}, exposing transaction-aware {@link Cache} objects
28+
* which synchronize their {@link Cache#put} operations with Spring-managed transactions
29+
* (through Spring's {@link org.springframework.transaction.support.TransactionSynchronizationManager},
30+
* performing the actual cache put operation only in the after-commit phase of a successful transaction.
31+
* If no transaction is active, {@link Cache#put} operations will be performed immediately, as usual.
32+
*
33+
* @author Juergen Hoeller
34+
* @since 3.2
35+
* @see #setTargetCacheManager
36+
* @see TransactionAwareCacheDecorator
37+
* @see org.springframework.transaction.support.TransactionSynchronizationManager
38+
*/
39+
public class TransactionAwareCacheManagerProxy implements CacheManager, InitializingBean {
40+
41+
private CacheManager targetCacheManager;
42+
43+
44+
/**
45+
* Create a new TransactionAwareCacheManagerProxy, setting the target CacheManager
46+
* through the {@link #setTargetCacheManager} bean property.
47+
*/
48+
public TransactionAwareCacheManagerProxy() {
49+
}
50+
51+
/**
52+
* Create a new TransactionAwareCacheManagerProxy for the given target CacheManager.
53+
* @param targetCacheManager the target CacheManager to proxy
54+
*/
55+
public TransactionAwareCacheManagerProxy(CacheManager targetCacheManager) {
56+
Assert.notNull(targetCacheManager, "Target CacheManager must not be null");
57+
this.targetCacheManager = targetCacheManager;
58+
}
59+
60+
61+
/**
62+
* Set the target CacheManager to proxy.
63+
*/
64+
public void setTargetCacheManager(CacheManager targetCacheManager) {
65+
this.targetCacheManager = targetCacheManager;
66+
}
67+
68+
public void afterPropertiesSet() {
69+
if (this.targetCacheManager == null) {
70+
throw new IllegalStateException("'targetCacheManager' is required");
71+
}
72+
}
73+
74+
75+
public Cache getCache(String name) {
76+
return new TransactionAwareCacheDecorator(this.targetCacheManager.getCache(name));
77+
}
78+
79+
public Collection<String> getCacheNames() {
80+
return this.targetCacheManager.getCacheNames();
81+
}
82+
83+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/**
2+
* Transaction-aware decorators for the the org.springframework.cache package.
3+
* Provides synchronization of put operations with Spring-managed transactions.
4+
*/
5+
package org.springframework.cache.transaction;

0 commit comments

Comments
 (0)