@Cacheable
和@CacheEvict 。 与所有Spring功能一样,您需要进行一定数量的设置,并且通常使用Spring的XML配置文件来完成。 在缓存的情况下,打开@Cacheable
和@CacheEvict
并不容易,因为您要做的就是将以下内容添加到Spring配置文件中: <cache:annotation-driven />
…以及您的beans
XML元素声明中的适当模式定义:
<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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.1.xsdhttp://www.springframework.org/schema/cachehttp://www.springframework.org/schema/cache/spring-cache.xsd'>
…的主要特点是:
xmlns:cache='http://www.springframework.org/schema/cache'
…和:
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
但是,这还不是故事的结局,因为您还需要指定一个缓存管理器和一个缓存实现。 好消息是,如果您熟悉其他Spring组件(例如数据库事务管理器)的设置,那么这样做的方式就不足为奇了。
缓存管理器类似乎是实现Spring的org.springframework.cache.CacheManager
接口的任何类。 它负责管理一个或多个缓存实施,其中缓存实施实例负责实际缓存数据。
下面的XML示例摘自我最近两个博客中使用的示例代码。
<bean id='cacheManager' class='org.springframework.cache.support.SimpleCacheManager'><property name='caches'><set><beanclass='org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean'p:name='employee'/><!-- TODO Add other cache instances in here--></set></property>
</bean>
在上面的配置中,我使用Spring的SimpleCacheManager
来管理其ConcurrentMapCacheFactoryBean
实例,该实例的缓存实现名为:“ employee
”。
需要注意的重要一点是,您的缓存管理器必须具有cacheManager
。 如果您弄错了,那么将得到以下异常:
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.NoSuchBeanDefinitionException: No bean named 'cacheManager' is definedat 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)
:
: trace details removed 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.NoSuchBeanDefinitionException:
No bean named 'cacheManager' is definedat org.springframework.beans.factory.support.DefaultListableBeanFactory.
getBeanDefinition(DefaultListableBeanFactory.java:553)at org.springframework.beans.factory.support.AbstractBeanFactory.
getMergedLocalBeanDefinition(AbstractBeanFactory.java:1095)at org.springframework.beans.factory.support.AbstractBeanFactory.
doGetBean(AbstractBeanFactory.java:277)at org.springframework.beans.factory.support.AbstractBeanFactory.
getBean(AbstractBeanFactory.java:193)at org.springframework.beans.factory.support.BeanDefinitionValueResolver.
resolveReference(BeanDefinitionValueResolver.java:322)
就像我在上面说的那样,在我的简单配置中,整个工作由SimpleCacheManager
协调。 根据文档,这通常是“用于测试或简单的缓存声明”。 尽管您可以编写自己的CacheManager
实现,但Spring的专家们为不同情况提供了其他缓存管理器
-
SimpleCacheManager
–参见上文。 -
NoOpCacheManager
–用于测试,因为它实际上并不缓存任何内容,尽管在这里要小心,因为在不进行缓存的情况下测试代码可能会在打开缓存时使您绊倒。 -
CompositeCacheManager
–允许在单个应用程序中使用多个缓存管理器。 -
EhCacheCacheManager
–包装ehCache
实例的缓存管理器。 见http://ehcache.org
对于Spring Profile
选择在任何给定环境中使用哪个缓存管理器似乎是一个很好的用途。 看到:?
- 在XML Config中使用Spring配置文件
- 使用Spring Profiles和Java配置
而且,尽管只是为了完整起见,但这只是将内容整理一下,下面是我前两个博客中使用的完整配置文件:
<?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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsdhttp://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' /><!-- simple cache manager --><bean id='cacheManager' class='org.springframework.cache.support.SimpleCacheManager'><property name='caches'><set><bean class='org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean' p:name='employee'/><!-- TODO Add other cache instances in here--></set></property></bean></beans>
正如哥伦波中尉喜欢说:“还有一件事,你知道让我为这个案件烦恼……”; 好吧,关于缓存管理器,有几件事让我感到困扰,例如:
- 在谈论SimpleCacheManager时,Spring的家伙们所说的“对测试或简单的缓存声明有用”是什么意思? 您究竟应该何时愤怒地使用它而不是进行测试?
- 最好编写自己的
CacheManager
实现,甚至是Cache
实现吗? - 使用
EhCacheCacheManager
确切优势是什么? - 您真正需要多少时间
CompositeCacheManager
?
我将来可能会研究所有这些……
祝您编程愉快,别忘了分享!
参考:来自Captain Debug's Blog博客的JCG合作伙伴 Roger Hughes的Spring 3.1 Caching and Config 。
翻译自: https://www.javacodegeeks.com/2012/09/spring-31-caching-and-config.html