(4)SprintBoot 2.X 通用Redis缓存Key的封装
1.为什么要对缓存Key进行封装?
当Redis存在大量的缓存引用时会导致一个问题,缓存key冲突,不能识别不同模块中的缓存(如相同的用户id和商品id不做任何修改,直接作为Redis的可以,就可能会导致key冲突) 解决:利用一个抽象类,定义BaseKey(前缀),在里面定义缓存key的前缀以及缓存的过期时间从而实现将缓存的key进行封装。让不同模块继承它,这样每次存入一个模块的缓存的时候,加上这个缓存特定的前缀,以及可以统一制定不同的过期时间。
2.代码实现
1. KeyPrefix接口
接口声明了两个方法,分别用于获取缓存key的的前缀以及有效期
public interface KeyPrefix {
public int expireSeconds ( ) ;
public String getPrefix ( ) ;
}
2. BasePrefix 抽象类
简单的实现一下KeyPrefix接口,定义成抽象类原因,防止不小心被创建,我们不希望BasePrefix被实例化,因为抽象类不允许实例化。我们只希望它被继承。不同模块的前缀类都继承他。
该抽象类中有两个构造方法,expireSeconds为0代表永不过期,另一个方法可以指定缓存key的有效期
public abstract class BasePrefix implements KeyPrefix {
private int expireSeconds;
private String prefix;
public BasePrefix ( String prefix) {
this ( 0 , prefix) ;
}
public BasePrefix ( int expireSeconds, String prefix) {
this . expireSeconds = expireSeconds;
this . prefix = prefix;
}
public int expireSeconds ( ) {
return expireSeconds;
}
public String getPrefix ( ) {
String className = getClass ( ) . getSimpleName ( ) ;
return className+ ":" + prefix;
}
}
3. 继承BasePerfix的具体实现类
public class UserKey extends BasePrefix {
public UserKey ( String prefix) {
super ( prefix) ;
}
public static UserKey getById = new UserKey ( "id" ) ;
public static UserKey getByName = new UserKey ( "name" ) ;
}
4. 具体使用场景,redisService的实现参考上一篇博客
使用该方法后存到redis中的键值对为(UserKey:id1,user)
@RequestMapping ( "/redis/get" )
@ResponseBody
public Result< User> redisGet ( ) {
User user = redisService. get ( UserKey. getById, "" + 1 , User. class ) ;
return Result. success ( user) ;
}
@RequestMapping ( "/redis/set" )
@ResponseBody
public Result< Boolean> redisSet ( ) {
User user = new User ( ) ;
user. setId ( 1 ) ;
user. setName ( "1111" ) ;
redisService. set ( UserKey. getById, "" + 1 , user) ;
return Result. success ( true ) ;
}