- 使用 threadLocal 获取数据源
- 实现
org.springframework.cache.interceptor. KeyGenerator
接口,重写 key 生成策略 - 配置全局key生成策略
https://github.com/spring-projects/spring-framework/issues/28250
public class MyKeyGenerator implements KeyGenerator {
private static final String SPLIT = "#";
@Override
public Object generate(Object target, Method method, Object... params) {
// 请求头+类名+方法名+参数【便于阅读】
// 可替换为 取数据摘要md5,长度减少,embstr->raw【性能更高,不便于阅读】
// 从threadLocal中获取想要的参数
String term = RoutingDataSourceContext.getDataSourceRoutingKey();
StringBuilder sb = new StringBuilder();
// request's header key
sb.append(term).append(SPLIT);
// class
sb.append(target.getClass().getSimpleName()).append(SPLIT);
// method
sb.append(method.getName());
// params
if (params.length == 0) {
return sb.toString();
}
sb.append(SPLIT);
if (params.length == 1) {
Object param = params[0];
if (param != null && !param.getClass().isArray()) {
return sb.append(Arrays.toString(params)).toString();
}
}
return sb.append("[").append(StringUtils.arrayToCommaDelimitedString(params)).append("]").toString();
}
public static KeyGenerator getInstance() {
return new MyKeyGenerator();
}
}
注入spring
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport{
@Override
@Bean
public KeyGenerator keyGenerator() {
return MyKeyGenerator.getInstance();
}
//...
}
使用
// 类统一配置
@CacheConfig(cacheNames = "user")
public class UserService {
// 方法结果进行缓存
@Cacheable
public User getById(Integer id) {
//...get by db
return user;
}
// 清除user类下的所有缓存
@CacheEvict(allEntries = true,cacheNames = "user")
public void update(){}
}