spring-boot整合redis作为缓存(3)——自定义key

来源:互联网 发布:linux 红旗 价钱 编辑:程序博客网 时间:2024/05/16 01:24
        分几篇文章总结spring-boot与Redis的整合

        1、redis的安装

        2、redis的设置

        3、spring-boot的缓存

        4、自定义key

        5、spring-boot引入Redis


        在上一篇文章中说道key是用来分辨同一个缓存中的缓存数据的。key是可以自己制定的,也可以通过自定义一个KeyGenerator来进行生成。

        所以我们自定义key的思路为:通过自定义一个KeyGenerator来生成自定义的key

        自定义key

        key可以为任何对象,我们要考虑的只有一件事,两个key对象,如何判断他们是否相等。所以很自然的我们想到重新实现它的hashCode和equals方法即可


        自定义keyGenerator

        自定义keyGenerator必须实现org.springframework.cache.interceptor.KeyGenerator接口,他有如下待实现方法

         Object generate(Object target, Method method, Object... params)

        参数:target为调用方法类的实例,method为调用的方法,params为调用方法传入的参数

        返回值:key对象

         实例

        这里举一个例子,也是很实用的例子,自定义一个key。key的相等逻辑为同一个类名,同一个方法名,同样的传参。

@Component("baseCacheKeyGenerator")public class BaseCacheKeyGenerator implements KeyGenerator {@Overridepublic Object generate(Object target, Method method, Object... params) {Object key=new BaseCacheKey(target,method,params);return key.toString();}}

public class BaseCacheKey implements Serializable{private static final long serialVersionUID = -1651889717223143579L;private static final Logger logger = LoggerFactory.getLogger(BaseCacheKey.class);private final Object[] params;private final int hashCode;private final String className;private final String methodName;public BaseCacheKey(Object target, Method method, Object[] elements){this.className=target.getClass().getName();this.methodName=getMethodName(method);this.params = new Object[elements.length];System.arraycopy(elements, 0, this.params, 0, elements.length);this.hashCode=generatorHashCode();}private String getMethodName(Method method){StringBuilder builder = new StringBuilder(method.getName());Class<?>[] types = method.getParameterTypes();if(types.length!=0){builder.append("(");for(Class<?> type:types){String name = type.getName();builder.append(name+",");}builder.append(")");}return builder.toString();} @Overridepublic boolean equals(Object obj){if(this==obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;BaseCacheKey o=(BaseCacheKey) obj;if(this.hashCode!=o.hashCode())return false;if(!Optional.ofNullable(o.className).orElse("").equals(this.className))return false;if(!Optional.ofNullable(o.methodName).orElse("").equals(this.methodName))return false;if (!Arrays.equals(params, o.params))return false;return true;}@Overridepublic final int hashCode() {return hashCode;}private int generatorHashCode() {final int prime = 31;int result = 1;result = prime * result + hashCode;result = prime * result + ((methodName == null) ? 0 : methodName.hashCode());result = prime * result + Arrays.deepHashCode(params);result = prime * result + ((className == null) ? 0 : className.hashCode());return result;}@Overridepublic String toString() {logger.debug(Arrays.toString(params));logger.debug(Arrays.deepToString(params));return "BaseCacheKey [params=" + Arrays.deepToString(params) + ", className=" + className + ", methodName="+ methodName + "]";}}

             注意:我为什么要返回一个字符串key.toString(),完全可以返回key。其实这里是为了解决redis中key为乱码的问题,这个在后一篇文章中会说明


0 0
原创粉丝点击