@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