到目前为止,我们已经实现了缓存周期灵活可控;缓存空间名称自动识别,目前还有一个需求还没有处理。
我想按一定规则设置缓存key,而且支持拼接参数值作为唯一标识。例如:
```
类名::参数1值:参数2值
```
我们知道CachingConfigurerSupport中暴露了keyGenerator 方法,他就是用来自定义缓存key的。
定义一个KeyParma 参数注解,用来标记哪些参数作为key的部分
```
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface KeyParam {
String key() default "";
}
```
实现keyGenerator 方法
```
public class CacheConfig extends CachingConfigurerSupport {
private final String KEY_SEPARATOR = ":";
@Override
public KeyGenerator keyGenerator() {
return (o, method, objects) -> {
StringBuilder sb = new StringBuilder();
//sb.append(o.getClass().getName());
Map<Integer, KeyParam> paramKeyMap = getParamKeyMap(method.getParameterAnnotations());
for (int i = 0; i < objects.length; i++) {
KeyParam keyParam = paramKeyMap.get(i);
if (null == keyParam) {
continue;
}
String key = keyParam.key();
Object paramObj = objects[i];
Object v = null;
//如果指定了key,则通过参数值获取指定属性值,否则直接将参数值作为缓存key部分
if (!StringUtils.isEmpty(key)) {
v = Beans.get(paramObj, key);
} else {
v = paramObj;
}
if (i == 0) {
sb.append(v);
} else {
sb.append(KEY_SEPARATOR).append(v);
}
}
return sb.toString();
};
}
//提取各个参数KeyParam,并放在map中
private Map<Integer, KeyParam> getParamKeyMap(Annotation[][] parameterAnnotations) {
Map<Integer, KeyParam> keyParamMap = Maps.newHashMap();
for (int i = 0; i < parameterAnnotations.length; i++) {
Annotation[] parameterAnnotation = parameterAnnotations[i];
for (Annotation annotation : parameterAnnotation) {
KeyParam keyParam = AnnotationUtils.getAnnotation(annotation, KeyParam.class);
if (null != keyParam) {
keyParamMap.put(i, keyParam);
}
}
}
return keyParamMap;
}
```
### 展示一下key
```
cn.cube.gopher.dao.impl.ThirdUserDao::onRqP4tixZh_lXvKhY8xi-hj1k3Y
```