欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot @Cacheable自定义KeyGenerator方式

程序员文章站 2022-03-18 21:19:16
目录@cacheable自定义keygenerator1. 概述2. mysimplekey 类3. mykeygenerator 类4. 配置keygeneratorspring-cache key...

@cacheable自定义keygenerator

1. 概述

springboot 使用 @cacheable 可以方便的管理缓存数据,在不指定 key 属性的情况下,默认使用 simplekeygenerator 生成 key。除此之外,我们也可以自定义实现 keygenerator 接口,生成自己的 key 名称策略。

2. mysimplekey 类

mysimplekey类的作用是存放参数数据,必须实现equals、hashcode。如果需要自定义key格式,同样需要实现tostring接口,下面的例子是把参数用逗号分隔。

public class mysimplekey implements serializable {
    public static final mysimplekey empty = new mysimplekey(new object[0]);
    private final object[] params;
    private transient int hashcode;
    public mysimplekey(object... elements) {
        assert.notnull(elements, "elements must not be null");
        this.params = (object[])elements.clone();
        this.hashcode = arrays.deephashcode(this.params);
    }
    public boolean equals(@nullable object other) {
        return this == other || other instanceof mysimplekey && arrays.deepequals(this.params, ((mysimplekey)other).params);
    }
    public final int hashcode() {
        return this.hashcode;
    }
    public string tostring() {
        return stringutils.arraytocommadelimitedstring(this.params);
    }
}

3. mykeygenerator 类

mykeygenerator 实现 keygenerator 的接口,里面只有一个 generate 方法

public class mykeygenerator implements keygenerator {
    @override
    public object generate(object o, method method, object... objects) {
        if (objects.length == 0) {
            return mysimplekey.empty;
        } else {
            if (objects.length == 1) {
                object param = objects[0];
                if (param != null && !param.getclass().isarray()) {
                    return param;
                }
            }
            return new mysimplekey(objects);
        }
    }
}

定义mykeygenerator bean:

@component
public class myredisconf {
    @bean
    public mykeygenerator mykeygenerator(){
        return new mykeygenerator();
    }
}

4. 配置keygenerator

在 @cacheable 配置 keygenerator 属性,值就是前面配置的bean名称

    @override
    @cacheable(value = {"redis:getstring3"}, keygenerator = "mykeygenerator")
    public string getstring3(string tag, string name) {
        return tag + " " + name;
    }

测试结果如下,tag、name 参数确实以逗号分隔

127.0.0.1:6379[5]> keys *

1) "redis:getstring3::hello,zhangsan"

spring-cache key设置

第一种方式:手动设置

为了便于key的不重复,我们可以手动设置key有类名、方法名、参数等组合

属性名称

描述

示例

methodname

当前方法名

#root.methodname

method

当前方法

#root.method.name

target

当前被调用的对象

#root.target

targetclass

当前被调用的对象的class

#root.targetclass

args

当前方法参数组成的数组

#root.args[0]

caches

当前被调用的方法使用的cache

#root.caches[0].name

key = "#root.targetclass.simplename+':'+#root.methodname+':'+#param"

如下图所示

SpringBoot @Cacheable自定义KeyGenerator方式

第二种方式:自定义keygenerator

1、自定义cachekeygenerator 实现keygenerator

public class cachekeygenerator implements keygenerator {
    /**
     * (非 javadoc)
     * <p>
     * title: generate
     * </p>
     * 
     * @param target
     * @param method
     * @param params
     * @return
     * @see org.springframework.cache.interceptor.keygenerator#generate(java.lang.object,
     *      java.lang.reflect.method, java.lang.object[])
     */
    @override
    public object generate(object target, method method, object... params) {
        stringbuilder key = new stringbuilder();
        key.append(target.getclass().getsimplename()).append(":").append(method.getname()).append(":");
        if (params.length == 0) {
            return key.tostring();
        }
        for (int i = 0; i < params.length; i++) {
            object param = params[i];
            if (param == null || param instanceof logableparam) {
                del(key);
            } else if (classutils.isprimitivearray(param.getclass())) {
                int length = array.getlength(param);
                for (int j = 0; j < length; j++) {
                    key.append(array.get(param, j));
                    key.append(',');
                }
            } else if (classutils.isprimitiveorwrapper(param.getclass()) || param instanceof string) {
                key.append(param);
            } else {
                key.append(param.tostring());
            }
            key.append('-');
        }
        del(key);
        return key.tostring();
    }
    private stringbuilder del(stringbuilder stringbuilder) {
        if (stringbuilder.tostring().endswith("-")) {
            stringbuilder.deletecharat(stringbuilder.length() - 1);
        }
        return stringbuilder;
    }
}

2、配置xml

<cache:annotation-driven cache-manager="cachemanager" key-generator="cachekeygenerator"
        proxy-target-class="true" />
<bean id="cachekeygenerator" class="com.tensoon.util.cachekeygenerator"></bean>

3、配置注解

如下图所示

SpringBoot @Cacheable自定义KeyGenerator方式

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。