理一理ehcache-spring-annotations缓存的Key生成
2017-09-26 11:40
363 查看
pom.xml
说明:
本文说的不是Spring Cache, ehcache-spring-annotations需要配合ehcache使用. 在代码中只是加注解(@Cacheable)而已
@Cacheable的全名: com.googlecode.ehcache.annotations.Cacheable,不要跟Spring Cache的同名注解(org.springframework.cache.annotation.Cacheable)混为一体
@Cacheable
说明:
keyGeneratorName和keyGenerator在下一篇中详细说说.refreshInterval默认是一分钟(60000L).一般只需要为cacheName设置一个值
缓存的Key
内存缓存大多都是key-value键值存储,注解中的keyGeneratorName和keyGenerator是可以指定一个自定义key生成策略.不指定默认使用的是:com.googlecode.ehcache.annotations.key.HashCodeCacheKeyGenerator
这里都不一一列出类的层次结构了.有兴趣的可以翻墙去下源码.下面是具体作生成的方法
说明:
MethodInvocation 在aopalliance-1.0.jar中的org.aopalliance.intercept包下,MethodInvocation 继承了Invocation可以拿到方法的参数值(getArguments),其它的都是反射包下的Method可以拿到的
method.getName()返回方法的名字
method.getReturnType()返回方法的返回值类型
method.getParameterTypes()返回方法的参数类型
在代码中定位一个方法的元素都有了:类全名 + 方法的签名(返回值 + 方法名 + 参数列表 )
参数的值不同也可以生成唯一的key
debug日志
ReflectiveMethodInvocation :
可见性修饰符(public) +
返回值类型(net.htage.forum.entity.ForumPermissions) +
方法全名(net.htage.forum.impl.service.spring.EhcacheCacheBox.getPermissions) +
( +
参数类型列表(net.htage.forum.entity.define.GlobalPermissionEnum) +
);
也说明如果一个方法没有参数,第一次调用生成key并缓存,以后的N次调用都是同一份缓存. 在debug日志中只能搜到一份记录
对于全局的配置来说没问题, N次调用后都是一样的结果. 但是?具有时间性的方法(同时它没有参数)则不然。第二次调用到第100调用之间数据肯定有变化的.哪这个默认的key生成策略还能用吗?
<!-- ehcache --> <dependency> <groupId>com.googlecode.ehcache-spring-annotations</groupId> <artifactId>ehcache-spring-annotations</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>${ehcache.version}</version> <type>pom</type> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>${ehcache.version}</version> </dependency>
说明:
本文说的不是Spring Cache, ehcache-spring-annotations需要配合ehcache使用. 在代码中只是加注解(@Cacheable)而已
@Cacheable(cacheName="myCache") public ForumPermissions getPermissions(GlobalPermissionEnum permissonType){ }
@Cacheable的全名: com.googlecode.ehcache.annotations.Cacheable,不要跟Spring Cache的同名注解(org.springframework.cache.annotation.Cacheable)混为一体
@Cacheable
@Target(value = {ElementType.METHOD}) @Retention(value = RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Cacheable { public String cacheName(); public boolean cacheNull() default true; public DecoratedCacheType decoratedCacheType() default DecoratedCacheType.NONE; @Deprecated public boolean selfPopulating() default false; public int selfPopulatingTimeout() default 0; public long refreshInterval() default 60000L; public String keyGeneratorName() default ""; public String exceptionCacheName() default ""; public KeyGenerator keyGenerator() default @KeyGenerator(name = ""); public String cacheableInteceptorName() default ""; public String resolverFactoryName() default ""; public ResolverFactory resolverFactory() default @ResolverFactory(name = ""); }
说明:
keyGeneratorName和keyGenerator在下一篇中详细说说.refreshInterval默认是一分钟(60000L).一般只需要为cacheName设置一个值
缓存的Key
内存缓存大多都是key-value键值存储,注解中的keyGeneratorName和keyGenerator是可以指定一个自定义key生成策略.不指定默认使用的是:com.googlecode.ehcache.annotations.key.HashCodeCacheKeyGenerator
package com.googlecode.ehcache.annotations.key; /** * @author Eric Dalquist * @version $Revision: 656 $ */ public class HashCodeCacheKeyGenerator extends AbstractHashingCacheKeyGenerator<HashCodeCacheKeyGenerator.LongGenerator, Long> {}
这里都不一一列出类的层次结构了.有兴趣的可以翻墙去下源码.下面是具体作生成的方法
package com.googlecode.ehcache.annotations.key; import java.io.Serializable; import java.lang.reflect.Method; import java.util.IdentityHashMap; import java.util.Map; import org.aopalliance.intercept.MethodInvocation; /** * Base class for cache key generators. Handles common logic for including/excluding the method * signature from key generation. Also provides support for avoiding circular references for key * generators that traverse the argument object graph via the {@link #register(Object)} and * {@link #unregister(Object)} APIs * * @author Eric Dalquist * @version $Revision: 656 $ */ public abstract class AbstractCacheKeyGenerator<T extends Serializable> implements CacheKeyGenerator<T> { //ETC /* (non-Javadoc) * @see com.googlecode.ehcache.annotations.key.CacheKeyGenerator#generateKey(org.aopalliance.intercept.MethodInvocation) */ public T generateKey(MethodInvocation methodInvocation) { final Object[] arguments = methodInvocation.getArguments(); if (this.includeMethod) { final Method method = methodInvocation.getMethod(); final Class<?> declaringClass = method.getDeclaringClass(); final String name = method.getName(); final Class<?> returnType = method.getReturnType(); if (this.includeParameterTypes) { final Class<?>[] parameterTypes = method.getParameterTypes(); return this.generateKey(declaringClass, name, returnType, parameterTypes, arguments); } return this.generateKey(declaringClass, name, returnType, arguments); } try { return this.generateKey(arguments); } finally { if (this.checkforCycles) { //Cleanup our thread local data REGISTRY.remove(); } } } }
说明:
MethodInvocation 在aopalliance-1.0.jar中的org.aopalliance.intercept包下,MethodInvocation 继承了Invocation可以拿到方法的参数值(getArguments),其它的都是反射包下的Method可以拿到的
method.getName()返回方法的名字
method.getReturnType()返回方法的返回值类型
method.getParameterTypes()返回方法的参数类型
在代码中定位一个方法的元素都有了:类全名 + 方法的签名(返回值 + 方法名 + 参数列表 )
参数的值不同也可以生成唯一的key
package com.googlecode.ehcache.annotations.interceptor; /** * Intercepter that handles invocations on methods annotated with {@link Cacheable} or {@link TriggersRemove}. * * @author Eric Dalquist * @version $Revision: 681 $ */ public class EhCacheInterceptor implements MethodInterceptor { //ETC /** * Creates a {@link Serializable} cache key from the {@link MethodInvocation} and configuration attributes. * * @param methodInvocation Invocation to build the key for * @param methodAttribute Configuration for the invoked method * @return Generated cache key, must not return null. */ protected Serializable generateCacheKey(MethodInvocation methodInvocation, final MethodAttribute methodAttribute) { final CacheKeyGenerator<? extends Serializable> cacheKeyGenerator = methodAttribute.getCacheKeyGenerator(); final ParameterMask parameterMask = methodAttribute.getCacheKeyParameterMask(); if (parameterMask.shouldMask()) { methodInvocation = new ParameterFilteringMethodInvocation(methodInvocation, parameterMask); } final Serializable cacheKey = cacheKeyGenerator.generateKey(methodInvocation); this.logger.debug("Generated key '{}' for invocation: {}", cacheKey, methodInvocation); return cacheKey; } }
debug日志
Generated key '-27052115907236245' for invocation: ReflectiveMethodInvocation: public net.htage.forum.entity.ForumPermissions net.htage.forum.impl.service.spring.EhcacheCacheBox.getPermissions(net.htage.forum.entity.define.GlobalPermissionEnum); target is of class [net.htage.forum.impl.service.spring.EhcacheCacheBox] Generated key '-27052113702228882' for invocation: ReflectiveMethodInvocation: public net.htage.forum.entity.ForumPermissions net.htage.forum.impl.service.spring.EhcacheCacheBox.getPermissions(net.htage.forum.entity.define.GlobalPermissionEnum); target is of class [net.htage.forum.impl.service.spring.EhcacheCacheBox]
ReflectiveMethodInvocation :
可见性修饰符(public) +
返回值类型(net.htage.forum.entity.ForumPermissions) +
方法全名(net.htage.forum.impl.service.spring.EhcacheCacheBox.getPermissions) +
( +
参数类型列表(net.htage.forum.entity.define.GlobalPermissionEnum) +
);
也说明如果一个方法没有参数,第一次调用生成key并缓存,以后的N次调用都是同一份缓存. 在debug日志中只能搜到一份记录
Generated key '-937817555943' for invocation: ReflectiveMethodInvocation: public java.util.List net.htage.forum.impl.service.spring.EhcacheCacheBox.getAllLevel(); target is of class [net.htage.forum.impl.service.spring.EhcacheCacheBox]
对于全局的配置来说没问题, N次调用后都是一样的结果. 但是?具有时间性的方法(同时它没有参数)则不然。第二次调用到第100调用之间数据肯定有变化的.哪这个默认的key生成策略还能用吗?
相关文章推荐
- Spring学习之缓存机制EhCache---Key
- Ehcache 整合Spring 使用页面、对象缓存
- Spring整合Ehcache3启动报错”Cache [xxx] specifies key/value types. Use getCache(String, Class, Class)”
- Spring整合Ehcache管理缓存
- 企业级框架____Ehcache缓存框架(Ehcache和Spring的整合)
- springboot+EHcache 实现文章浏览量的缓存和超时更新
- springboot+EHcache 实现文章浏览量的缓存和超时更新
- (转)使用 Spring缓存抽象 支持 EhCache 和 Redis 混合部署
- Ehcache 整合Spring 使用页面、对象缓存
- Ehcache 整合Spring 使用页面、对象缓存
- Spring整合Ehcache管理缓存
- java缓存EHCache Spring MVC项目配置ehcache
- Spring+ehcache缓存实例
- 利用 Spring 和 EHCache 缓存结果(翻译)
- 在Spring、Hibernate中使用Ehcache缓存--Ehcache 整合Spring 使用页面、对象缓存
- springMVC+mybatis+ehcache缓存配置实践
- Spring+EhCache缓存实例(详细讲解+源码下载)(转)
- Ehcache 整合Spring 使用页面、对象缓存
- Ehcache 整合Spring 使用页面、对象缓存