背景
使用ehcache实现@Cacheable
时,默认的缓存键(key)是采用对应方法的参数值的组合,这样,如果程序广泛使用ehcache做缓存很容易造成key的冲突,导致缓存信息错乱。
默认ehcache有提供三种KeyGenerator
- DefaultKeyGenerator
- KeyGeneratorAdapter
- SimpleKeyGenerator
但是这三种都相对简单,下面就介绍一下怎么自定义KeyGenerator,并提供一个相对通用的方法。
自定义Cache KeyGenerator
代码方式
|
配置方式
定义单独的Key Generator Class
import java.lang.reflect.Method; |
对应spring的完整配置文件如下:<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<context:component-scan base-package="com.crunchify.controller" />
<mvc:annotation-driven></mvc:annotation-driven>
<cache:annotation-driven cache-manager="ehcacheCacheManager" />
<cache:annotation-driven key-generator="enhancedDefaultKeyGenerator" />
<bean id="enhancedDefaultKeyGenerator"
class="com.crunchify.controller.EnhancedDefaultKeyGenerator" />
<bean id="ehcacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:main/resource/ehcache.xml" />
</bean>
<bean id="ehcacheCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="ehcacheManager" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
其中添加了对应cache的一些支持,代码:xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
<cache:annotation-driven cache-manager="ehcacheCacheManager" />
<cache:annotation-driven key-generator="enhancedDefaultKeyGenerator" />
<bean id="enhancedDefaultKeyGenerator"
class="com.crunchify.controller.EnhancedDefaultKeyGenerator" />
<bean id="ehcacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:main/resource/ehcache.xml" />
</bean>
<bean id="ehcacheCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="ehcacheManager" />
这里定义的key的结构为:类名:方法名:(参数值以|分割)
, 示例如下:
实现代码:@Cacheable(value = "cache1")
public Movie findByDirector(String name) {
//...
return null;
}
obj.findByDirector("dummy")
这是对应的key为:com.demo.test.MovieDaoImpl:findByDirector:|dummy
查看当前缓存里的内容:
|
这样,对应ehcache里的内容就被打印出来了,如下:
## CacheName: cache2 cache records: 0 heap size: 0 bytes disk size: 0 bytes ## CacheName: cache1 heap size: 760 bytes disk size: 803 bytes - key: com.demo.test.MovieDaoImpl:findByDirector:|dummy2, value: com.demo.test.Movie@71ba6d4e, hit: 1, created: 1452027528985, expiration: 1452027829081 - key: com.demo.test.MovieDaoImpl:findByDirector:|dummy, value: com.demo.test.Movie@55a147cc, hit: 2, created: 1452027526982, expiration: 1452027829081 |
参考
对应的ehcache.xml文件
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
可以借鉴的一些KeyGenerator
- 具体配置:https://github.com/agentgt/ehcache-spring-annotations/blob/master/core/src/test/resources/performanceTestContext.xml
- 代码实现: https://github.com/agentgt/ehcache-spring-annotations/tree/master/core/src/main/java/com/googlecode/ehcache/annotations/key