Spring 3.1:缓存和EhCache

如果在网上查找使用Spring 3.1内置缓存的示例,那么通常会碰到Spring的SimpleCacheManager ,Spring的家伙说这对“用于测试或简单的缓存声明很有用”。 实际上,我更喜欢将SimpleCacheManager看作是轻量级的,而不是简单的。 在您希望每个JVM占用少量内存缓存的情况下很有用。 如果Spring的家伙正在经营一家超市,那么SimpleCacheManager将属于他们自己品牌的“基本”产品范围。

另一方面,如果您需要一个可扩展,持久和分布式的重型缓存,则Spring还附带内置的ehCache包装器。

好消息是,Spring的缓存实现之间的交换很容易。 从理论上讲,这完全是配置问题,为了证明该理论正确,我从Caching和@Cacheable博客中获取了示例代码,并使用EhCache实现对其进行了运行。

配置步骤与我上一篇博客“ 缓存和配置”中描述的步骤相似,您仍然需要指定:

<cache:annotation-driven />

…在您的Spring配置文件中以打开缓存。 您还需要定义一个id为cacheManager的bean,只是这一次您引用Spring的EhCacheCacheManager类而不是SimpleCacheManager

<bean id='cacheManager'
    class='org.springframework.cache.ehcache.EhCacheCacheManager'
    p:cacheManager-ref='ehcache'/>

上面的示例演示了EhCacheCacheManager配置。 注意,它引用了另一个ID为“ ehcache ”的bean。 配置如下:

<bean id='ehcache' class='org.springframework.cache.ehcache.EhCacheManagerFactoryBean'
    p:configLocation='ehcache.xml'
    p:shared='true'/>

ehcache ”具有两个属性: configLocationshared
configLocation ”是一个可选属性,用于指定ehcache配置文件的位置。 在测试代​​码中,我使用了以下示例文件:

<?xml version='1.0' encoding='UTF-8'?>
<ehcache xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='http://ehcache.org/ehcache.xsd'>
    <defaultCache eternal='true' maxElementsInMemory='100' overflowToDisk='false' />
    <cache name='employee' maxElementsInMemory='10000' eternal='true' overflowToDisk='false' />
</ehcache>

…这将创建两个缓存:一个默认缓存和一个名为“员工”的缓存。

如果缺少此文件,则EhCacheManagerFactoryBean只需选择一个默认的ehcache配置文件: ehcache-failsafe.xml ,该文件位于ehcache的ehcache-core jar文件中。

另一个EhCacheManagerFactoryBean属性是' shared '。 这被认为是可选的,因为文档指出它定义了“ EHCache CacheManager是应该共享(作为VM级别的单例)还是独立的(通常在应用程序内部)。 默认值为'false',创建一个独立的实例。” 但是,如果将其设置为false,则将收到以下异常:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.interceptor.CacheInterceptor#0': Cannot resolve reference to bean 'cacheManager' while setting bean property 'cacheManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cacheManager' defined in class path resource [ehcache-example.xml]: Cannot resolve reference to bean 'ehcache' while setting bean property 'cacheManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ehcache' defined in class path resource [ehcache-example.xml]: Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.
The source of the existing CacheManager is: InputStreamConfigurationSource [stream=java.io.BufferedInputStream@424c414]
 at org.springframework.beans.factory.support.BeanDefinitionValueResolver.
resolveReference(BeanDefinitionValueResolver.java:328)
 at org.springframework.beans.factory.support.BeanDefinitionValueResolver.
resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
populateBean(AbstractAutowireCapableBeanFactory.java:1118)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
createBean(AbstractAutowireCapableBeanFactory.java:456)
... stack trace shortened for clarity
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.
java:683)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.
run(RemoteTestRunner.java:390)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.
main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cacheManager' defined in class path resource [ehcache-example.xml]: Cannot resolve reference to bean 'ehcache' while setting bean property 'cacheManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ehcache' defined in class path resource [ehcache-example.xml]: Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.
The source of the existing CacheManager is: InputStreamConfigurationSource [stream=java.io.BufferedInputStream@424c414]
 at org.springframework.beans.factory.support.BeanDefinitionValueResolver.
resolveReference(BeanDefinitionValueResolver.java:328)
 at org.springframework.beans.factory.support.BeanDefinitionValueResolver.
resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360)
... stack trace shortened for clarity
 at org.springframework.beans.factory.support.AbstractBeanFactory.
getBean(AbstractBeanFactory.java:193)
 at org.springframework.beans.factory.support.BeanDefinitionValueResolver.
resolveReference(BeanDefinitionValueResolver.java:322)
 ... 38 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ehcache' defined in class path resource [ehcache-example.xml]: Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.
The source of the existing CacheManager is: InputStreamConfigurationSource [stream=java.io.BufferedInputStream@424c414]
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
initializeBean(AbstractAutowireCapableBeanFactory.java:1455)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
createBean(AbstractAutowireCapableBeanFactory.java:456)
 at org.springframework.beans.factory.support.AbstractBeanFactory$1
.getObject(AbstractBeanFactory.java:294)
 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.
getSingleton(DefaultSingletonBeanRegistry.java:225)
 at org.springframework.beans.factory.support.AbstractBeanFactory.
doGetBean(AbstractBeanFactory.java:291)
 at org.springframework.beans.factory.support.AbstractBeanFactory.
getBean(AbstractBeanFactory.java:193)
 at org.springframework.beans.factory.support.BeanDefinitionValueResolver.
resolveReference(BeanDefinitionValueResolver.java:322)
 ... 48 more
Caused by: net.sf.ehcache.CacheException: Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.
The source of the existing CacheManager is: InputStreamConfigurationSource [stream=java.io.BufferedInputStream@424c414]
 at net.sf.ehcache.CacheManager.assertNoCacheManagerExistsWithSameName(CacheManager.
java:521)
 at net.sf.ehcache.CacheManager.init(CacheManager.java:371)
 at net.sf.ehcache.CacheManager.
                    
                     (CacheManager.java:339)
 at org.springframework.cache.ehcache.EhCacheManagerFactoryBean.
afterPropertiesSet(EhCacheManagerFactoryBean.java:104)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
 ... 55 more

…当您尝试运行一系列单元测试时。

我认为这归结为Spring的ehcache管理器工厂的一个简单错误,因为它试图使用new()创建多个缓存实例,而不是使用“其中一种CacheManager.create()静态工厂方法”作为例外,允许其重用相同名称的相同CacheManager。 因此,我的第一个JUnit测试工作正常,但其他所有测试均失败。

令人反感的代码行是:

this.cacheManager = (this.shared ? CacheManager.create() : new CacheManager());

为了完整性,下面列出了我的完整XML配置文件:

<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns='http://www.springframework.org/schema/beans' 
  xmlns:p='http://www.springframework.org/schema/p'
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:cache='http://www.springframework.org/schema/cache' 
  xmlns:context='http://www.springframework.org/schema/context'
   xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd'>
 
  <!-- Switch on the Caching -->
   <cache:annotation-driven />

 <!-- Do the component scan path -->
 <context:component-scan base-package='caching' />

 <bean id='cacheManager' class='org.springframework.cache.ehcache.EhCacheCacheManager' 
  p:cacheManager-ref='ehcache'/>
 
 <bean id='ehcache' class='org.springframework.cache.ehcache.EhCacheManagerFactoryBean' 
     p:configLocation='ehcache.xml'  
     p:shared='true'/> 
</beans>

在使用ehcache时,要考虑的唯一其他配置详细信息是Maven依赖项。 这些非常简单,因为Ehcache的专家们将所有各种ehcache jar组合到一个Maven POM模块中。 可以使用下面的XML将该POM模块添加到项目的POM文件中:

<dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>2.6.0</version>
        <type>pom</type>
        <scope>test</scope>
    </dependency>

最后,可以从Maven Central和Sourceforge存储库中获得ehcache Jar文件:

<repositories>
        <repository>
            <id>sourceforge</id>
            <url>http://oss.sonatype.org/content/groups/sourceforge/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

祝您编程愉快,别忘了分享!

参考: Spring 3.1:来自Captain Debug's Blog博客的JCG合作伙伴 Roger Hughes的缓存和EhCache


翻译自: https://www.javacodegeeks.com/2012/10/spring-31-caching-and-ehcache.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值