All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.xuqiudong.common.base.cache.CommonKeyGenerator Maven / Gradle / Ivy

package cn.xuqiudong.common.base.cache;


import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.util.Date;

/**
 * 描述:这是一个简单的缓存key生成器,满足key为简单参数的缓存处理器: 一般只作用在方法级别的注解上;
 * 之所以在生成的key上没有加上方法名,是因为对于一个资源既可能是缓存,也可能是驱逐,二者的需要能一致;
 * 

* 1.使用方法,把此方法注入spring, bean的name设置为 CommonKeyGenerator.GENERATOR_NAME * 2. 缓存方法的Cacheable/CacheEvict/CachePut注解的keyGenerator属性设置为CommonKeyGenerator.GENERATOR_NAME *

* @author Vic.xu * @date 2021-12-07 9:24 */ public class CommonKeyGenerator implements KeyGenerator { /** * 当前bean注册到容器的时候,使用的名字 和本参数保持一致,方便在缓存注解中使用此参数 */ public static final String GENERATOR_NAME = "commonKeyGenerator"; /** * 这个分隔符非常重要,请自行查看REDIS命名空间相关 */ private static final String DELIMITER = ":"; /** * 若多个参数 组成key的时候的连接符 */ private static final String PARAMS_DELIMITER = "-"; /** * 万一参数是空呢 */ private static final String EMPTY = "0"; /** * 缓存key的默认前缀 */ private static final String DEFAULT_PREFIX = "cache"; /** * 缓存key的前缀 */ private String prefix; public String getPrefix() { return prefix; } public void setPrefix(String prefix) { this.prefix = prefix; } /** * 缓存方法名:方法名:参数-参数-参数 */ @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append(getCacheName(method)).append(DELIMITER); if (params == null || params.length == 0) { sb.append(EMPTY); } else { for (Object param : params) { if (param == null) { continue; } //简单数据类型取自身 非简单数据类型取hashcode if (!isSimpleType(param.getClass())) { param = param.hashCode(); } sb.append(param).append(PARAMS_DELIMITER); } } //删除掉最后一个分隔符号 if (sb.toString().endsWith(PARAMS_DELIMITER)) { sb.deleteCharAt(sb.length() - 1); } return sb.toString(); } /** * 是否是简单的数据类型:此处只做部分简单的判断8中基本数据类型及包装类和string /Number /date * @return */ public static boolean isSimpleType(Class clazz) { return ClassUtils.isPrimitiveOrWrapper(clazz) || CharSequence.class.isAssignableFrom(clazz) || Number.class.isAssignableFrom(clazz) || Date.class.isAssignableFrom(clazz); } /** * 获取方法去上的缓存方法, 并新增前缀 * @param method * @return */ private String getCacheName(Method method) { String cacheName = ""; if (method.isAnnotationPresent(Cacheable.class)) { Cacheable cacheable = method.getAnnotation(Cacheable.class); cacheName = getFirstCacheName(cacheable.value()); } else if (method.isAnnotationPresent(CacheEvict.class)) { CacheEvict cacheable = method.getAnnotation(CacheEvict.class); cacheName = getFirstCacheName(cacheable.value()); } else if (method.isAnnotationPresent(CachePut.class)) { CachePut cacheable = method.getAnnotation(CachePut.class); cacheName = getFirstCacheName(cacheable.value()); } return addPrefix(cacheName); } /** * 增加前缀 * @param cacheName * @return */ private String addPrefix(String cacheName) { String prefix = StringUtils.isEmpty(getPrefix()) ? DEFAULT_PREFIX : getPrefix(); return prefix + DELIMITER + cacheName; } private static String getFirstCacheName(String[] names) { if (names != null && names.length > 0) { return names[0]; } return ""; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy