Convenient EhCache CacheManager bootstrapping within @Bean methods

Also introducing default CacheManager setup for EhCacheCacheManager, analogous to JCacheCacheManager.

Issue: SPR-12093
This commit is contained in:
Juergen Hoeller 2014-08-18 19:25:40 +02:00
parent b910ff34e6
commit 0d0d7139ee
4 changed files with 163 additions and 47 deletions

View File

@ -69,19 +69,25 @@ public class EhCacheCacheManager extends AbstractTransactionSupportingCacheManag
return this.cacheManager;
}
@Override
public void afterPropertiesSet() {
if (getCacheManager() == null) {
setCacheManager(EhCacheManagerUtils.buildCacheManager());
}
super.afterPropertiesSet();
}
@Override
protected Collection<Cache> loadCaches() {
net.sf.ehcache.CacheManager cacheManager = getCacheManager();
Assert.notNull(cacheManager, "A backing EhCache CacheManager is required");
Status status = cacheManager.getStatus();
Status status = getCacheManager().getStatus();
Assert.isTrue(Status.STATUS_ALIVE.equals(status),
"An 'alive' EhCache CacheManager is required - current cache is " + status.toString());
String[] names = cacheManager.getCacheNames();
String[] names = getCacheManager().getCacheNames();
Collection<Cache> caches = new LinkedHashSet<Cache>(names.length);
for (String name : names) {
caches.add(new EhCacheCache(cacheManager.getEhcache(name)));
caches.add(new EhCacheCache(getCacheManager().getEhcache(name)));
}
return caches;
}

View File

@ -16,7 +16,6 @@
package org.springframework.cache.ehcache;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Set;
@ -231,7 +230,7 @@ public class EhCacheFactoryBean extends CacheConfiguration implements FactoryBea
@Override
public void afterPropertiesSet() throws CacheException, IOException {
public void afterPropertiesSet() throws CacheException {
// If no cache name given, use bean name as cache name.
String cacheName = getName();
if (cacheName == null) {

View File

@ -16,9 +16,6 @@
package org.springframework.cache.ehcache;
import java.io.IOException;
import java.io.InputStream;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.config.Configuration;
@ -97,9 +94,6 @@ public class EhCacheManagerFactoryBean implements FactoryBean<CacheManager>, Ini
* but will simply work with the default CacheManager name if none specified.
* All references to the same CacheManager name (or the same default) in the
* same ClassLoader space will share the specified CacheManager then.
* <p><b>NOTE:</b> This feature requires EhCache 2.5 or higher. In contrast to
* the {@link #setShared "shared"} flag, it supports controlled shutdown of the
* CacheManager by the EhCacheManagerFactoryBean that actually created it.
* @see #setCacheManagerName
* #see #setShared
* @see net.sf.ehcache.CacheManager#getCacheManager(String)
@ -131,44 +125,36 @@ public class EhCacheManagerFactoryBean implements FactoryBean<CacheManager>, Ini
@Override
public void afterPropertiesSet() throws IOException, CacheException {
public void afterPropertiesSet() throws CacheException {
logger.info("Initializing EhCache CacheManager");
InputStream is = (this.configLocation != null ? this.configLocation.getInputStream() : null);
try {
Configuration configuration = (is != null ?
ConfigurationFactory.parseConfiguration(is) : ConfigurationFactory.parseConfiguration());
if (this.cacheManagerName != null) {
configuration.setName(this.cacheManagerName);
}
if (this.shared) {
// Old-school EhCache singleton sharing...
// No way to find out whether we actually created a new CacheManager
// or just received an existing singleton reference.
this.cacheManager = CacheManager.create(configuration);
}
else if (this.acceptExisting) {
// EhCache 2.5+: Reusing an existing CacheManager of the same name.
// Basically the same code as in CacheManager.getInstance(String),
// just storing whether we're dealing with an existing instance.
synchronized (CacheManager.class) {
this.cacheManager = CacheManager.getCacheManager(this.cacheManagerName);
if (this.cacheManager == null) {
this.cacheManager = new CacheManager(configuration);
}
else {
this.locallyManaged = false;
}
Configuration configuration = (this.configLocation != null ?
EhCacheManagerUtils.parseConfiguration(this.configLocation) : ConfigurationFactory.parseConfiguration());
if (this.cacheManagerName != null) {
configuration.setName(this.cacheManagerName);
}
if (this.shared) {
// Old-school EhCache singleton sharing...
// No way to find out whether we actually created a new CacheManager
// or just received an existing singleton reference.
this.cacheManager = CacheManager.create(configuration);
}
else if (this.acceptExisting) {
// EhCache 2.5+: Reusing an existing CacheManager of the same name.
// Basically the same code as in CacheManager.getInstance(String),
// just storing whether we're dealing with an existing instance.
synchronized (CacheManager.class) {
this.cacheManager = CacheManager.getCacheManager(this.cacheManagerName);
if (this.cacheManager == null) {
this.cacheManager = new CacheManager(configuration);
}
else {
this.locallyManaged = false;
}
}
else {
// Throwing an exception if a CacheManager of the same name exists already...
this.cacheManager = new CacheManager(configuration);
}
}
finally {
if (is != null) {
is.close();
}
else {
// Throwing an exception if a CacheManager of the same name exists already...
this.cacheManager = new CacheManager(configuration);
}
}

View File

@ -0,0 +1,125 @@
/*
* Copyright 2002-2014 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 java.io.IOException;
import java.io.InputStream;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.config.Configuration;
import net.sf.ehcache.config.ConfigurationFactory;
import org.springframework.core.io.Resource;
/**
* Convenient builder methods for EhCache 2.5+ {@link CacheManager} setup,
* providing easy programmatic bootstrapping from a Spring-provided resource.
* This is primarily intended for use within {@code @Bean} methods in a
* Spring configuration class.
*
* <p>These methods are a simple alternative to custom {@link CacheManager} setup
* code. For any advanced purposes, consider using {@link #parseConfiguration},
* customizing the configuration object, and then calling the
* {@link CacheManager#CacheManager(Configuration)} constructor.
*
* @author Juergen Hoeller
* @since 4.1
*/
public abstract class EhCacheManagerUtils {
/**
* Build an EhCache {@link CacheManager} from the default configuration.
* <p>The CacheManager will be configured from "ehcache.xml" in the root of the class path
* (that is, default EhCache initialization - as defined in the EhCache docs - will apply).
* If no configuration file can be found, a fail-safe fallback configuration will be used.
* @return the new EhCache CacheManager
* @throws CacheException in case of configuration parsing failure
*/
public static CacheManager buildCacheManager() throws CacheException {
return new CacheManager(ConfigurationFactory.parseConfiguration());
}
/**
* Build an EhCache {@link CacheManager} from the default configuration.
* <p>The CacheManager will be configured from "ehcache.xml" in the root of the class path
* (that is, default EhCache initialization - as defined in the EhCache docs - will apply).
* If no configuration file can be found, a fail-safe fallback configuration will be used.
* @param name the desired name of the cache manager
* @return the new EhCache CacheManager
* @throws CacheException in case of configuration parsing failure
*/
public static CacheManager buildCacheManager(String name) throws CacheException {
Configuration configuration = ConfigurationFactory.parseConfiguration();
configuration.setName(name);
return new CacheManager(configuration);
}
/**
* Build an EhCache {@link CacheManager} from the given configuration resource.
* @param configLocation the location of the configuration file (as a Spring resource)
* @return the new EhCache CacheManager
* @throws CacheException in case of configuration parsing failure
*/
public static CacheManager buildCacheManager(Resource configLocation) throws CacheException {
return new CacheManager(parseConfiguration(configLocation));
}
/**
* Build an EhCache {@link CacheManager} from the given configuration resource.
* @param name the desired name of the cache manager
* @param configLocation the location of the configuration file (as a Spring resource)
* @return the new EhCache CacheManager
* @throws CacheException in case of configuration parsing failure
*/
public static CacheManager buildCacheManager(String name, Resource configLocation) throws CacheException {
Configuration configuration = parseConfiguration(configLocation);
configuration.setName(name);
return new CacheManager(configuration);
}
/**
* Parse EhCache configuration from the given resource, for further use with
* custom {@link CacheManager} creation.
* @param configLocation the location of the configuration file (as a Spring resource)
* @return the EhCache Configuration handle
* @throws CacheException in case of configuration parsing failure
* @see CacheManager#CacheManager(Configuration)
* @see CacheManager#create(Configuration)
*/
public static Configuration parseConfiguration(Resource configLocation) throws CacheException {
InputStream is = null;
try {
is = configLocation.getInputStream();
return ConfigurationFactory.parseConfiguration(is);
}
catch (IOException ex) {
throw new CacheException("Failed to parse EhCache configuration resource", ex);
}
finally {
if (is != null) {
try {
is.close();
}
catch (IOException ex) {
// ignore
}
}
}
}
}