redis 支持自定义动态前缀

This commit is contained in:
b2baccline
2021-11-14 10:26:07 +08:00
parent f085bfbbcf
commit 370880b4b1
7 changed files with 142 additions and 50 deletions

View File

@@ -0,0 +1,76 @@
package com.hccake.ballcat.common.redis.prefix;
import cn.hutool.core.text.CharSequenceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;
/**
* redis key前缀生成器
*
* @author huyuanzhi
*/
public interface IRedisPrefixConverter {
Logger LOGGER = LoggerFactory.getLogger(IRedisPrefixConverter.class);
/**
* 生成前缀
* @return 前缀
*/
String getPrefix();
/**
* 是否启用
* @return 是否启用
*/
boolean enable();
/**
* 去除key前缀
* @param bytes key字节数组
* @return 原始key
*/
default byte[] unwrap(byte[] bytes) {
int wrapLen;
if (!enable() || bytes == null || (wrapLen = bytes.length) == 0) {
return bytes;
}
String prefix = getPrefix();
if (CharSequenceUtil.isBlank(prefix)) {
LOGGER.warn("prefix converter is enabled,but method getPrefix returns blank result,check your implement!");
return bytes;
}
byte[] prefixBytes = prefix.getBytes(StandardCharsets.UTF_8);
int prefixLen = prefixBytes.length;
int originLen = wrapLen - prefixLen;
byte[] originBytes = new byte[originLen];
System.arraycopy(bytes, prefixLen, originBytes, 0, originLen);
return originBytes;
}
/**
* 给key加上固定前缀
* @param bytes 原始key字节数组
* @return 加前缀之后的key
*/
default byte[] wrap(byte[] bytes) {
int originLen;
if (!enable() || bytes == null || (originLen = bytes.length) == 0) {
return bytes;
}
String prefix = getPrefix();
if (CharSequenceUtil.isBlank(prefix)) {
LOGGER.warn("prefix converter is enabled,but method getPrefix returns blank result,check your implement!");
return bytes;
}
byte[] prefixBytes = prefix.getBytes(StandardCharsets.UTF_8);
int prefixLen = prefixBytes.length;
byte[] wrapBytes = new byte[prefixLen + originLen];
System.arraycopy(prefixBytes, 0, wrapBytes, 0, prefixLen);
System.arraycopy(bytes, 0, wrapBytes, prefixLen, originLen);
return wrapBytes;
}
}

View File

@@ -0,0 +1,28 @@
package com.hccake.ballcat.common.redis.prefix.impl;
import com.hccake.ballcat.common.redis.prefix.IRedisPrefixConverter;
/**
* redis key前缀默认转换器
*
* @author huyuanzhi
*/
public class DefaultRedisPrefixConverter implements IRedisPrefixConverter {
private final String prefix;
public DefaultRedisPrefixConverter(String prefix) {
this.prefix = prefix;
}
@Override
public String getPrefix() {
return prefix;
}
@Override
public boolean enable() {
return true;
}
}

View File

@@ -1,5 +1,6 @@
package com.hccake.ballcat.common.redis.serialize;
import com.hccake.ballcat.common.redis.prefix.IRedisPrefixConverter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
@@ -11,40 +12,22 @@ import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
@Slf4j
public class PrefixJdkRedisSerializer extends JdkSerializationRedisSerializer {
private final String prefix;
private final IRedisPrefixConverter redisPrefixConverter;
private final boolean enable;
public PrefixJdkRedisSerializer(String prefix) {
this.prefix = prefix;
this.enable = prefix != null && !"".equals(prefix);
public PrefixJdkRedisSerializer(IRedisPrefixConverter redisPrefixConverter) {
this.redisPrefixConverter = redisPrefixConverter;
}
@Override
public Object deserialize(byte[] bytes) {
Object origin = super.deserialize(bytes);
if (enable && origin instanceof String) {
String originKey = (String) origin;
// 如果有全局前缀,则需要删除
if (originKey.startsWith(prefix)) {
originKey = originKey.substring(prefix.length());
}
return originKey;
}
else {
return origin;
}
byte[] unwrap = redisPrefixConverter.unwrap(bytes);
return super.deserialize(unwrap);
}
@Override
public byte[] serialize(Object object) {
if (enable && object instanceof String) {
String key = prefix + object;
return super.serialize(key);
}
else {
return super.serialize(object);
}
byte[] originBytes = super.serialize(object);
return redisPrefixConverter.wrap(originBytes);
}
}

View File

@@ -1,5 +1,6 @@
package com.hccake.ballcat.common.redis.serialize;
import com.hccake.ballcat.common.redis.prefix.IRedisPrefixConverter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@@ -13,32 +14,23 @@ import java.nio.charset.StandardCharsets;
@Slf4j
public class PrefixStringRedisSerializer extends StringRedisSerializer {
private final String prefix;
private final IRedisPrefixConverter iRedisPrefixConverter;
private final boolean enable;
public PrefixStringRedisSerializer(String prefix) {
public PrefixStringRedisSerializer(IRedisPrefixConverter iRedisPrefixConverter) {
super(StandardCharsets.UTF_8);
this.prefix = prefix;
this.enable = prefix != null && !"".equals(prefix);
this.iRedisPrefixConverter = iRedisPrefixConverter;
}
@Override
public String deserialize(byte[] bytes) {
String originKey = super.deserialize(bytes);
// 如果有全局前缀,则需要删除
if (enable && originKey != null && originKey.startsWith(prefix)) {
originKey = originKey.substring(prefix.length());
}
return originKey;
byte[] unwrap = iRedisPrefixConverter.unwrap(bytes);
return super.deserialize(unwrap);
}
@Override
public byte[] serialize(String string) {
if (enable && string != null) {
string = prefix + string;
}
return super.serialize(string);
public byte[] serialize(String key) {
byte[] originBytes = super.serialize(key);
return iRedisPrefixConverter.wrap(originBytes);
}
}