parent
2ef96ad31b
commit
3f71c2c0d7
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>opsli-plugins</artifactId>
|
||||||
|
<groupId>org.opsliframework.boot</groupId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>opsli-plugins-redis</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- 集成Redis缓存 BEGIN -->
|
||||||
|
<!-- Redis -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 集成Redis缓存 END -->
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,102 @@
|
|||||||
|
package org.opsli.plugins.redis.conf;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.opsli.common.utils.PackageUtil;
|
||||||
|
import org.opsli.plugins.redis.msg.RedisMsg;
|
||||||
|
import org.opsli.plugins.redis.scripts.RedisPluginScript;
|
||||||
|
import org.opsli.plugins.redis.scripts.RedisScriptCache;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||||
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author parker
|
||||||
|
*
|
||||||
|
* Redis 配置类
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Configuration
|
||||||
|
public class RedisPluginConfig {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private LettuceConnectionFactory factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RedisTemplate配置
|
||||||
|
* 序列化设置
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public RedisTemplate<String, Object> redisTemplate() {
|
||||||
|
RedisTemplate<String, Object> template = new RedisTemplate<>();
|
||||||
|
template.setConnectionFactory(factory);
|
||||||
|
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
||||||
|
ObjectMapper om = new ObjectMapper();
|
||||||
|
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||||
|
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||||
|
jackson2JsonRedisSerializer.setObjectMapper(om);
|
||||||
|
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
|
||||||
|
// key采用String的序列化方式
|
||||||
|
template.setKeySerializer(stringRedisSerializer);
|
||||||
|
// hash的key也采用String的序列化方式
|
||||||
|
template.setHashKeySerializer(stringRedisSerializer);
|
||||||
|
// value序列化方式采用jackson
|
||||||
|
template.setValueSerializer(jackson2JsonRedisSerializer);
|
||||||
|
// hash的value序列化方式采用jackson
|
||||||
|
template.setHashValueSerializer(jackson2JsonRedisSerializer);
|
||||||
|
template.afterPropertiesSet();
|
||||||
|
|
||||||
|
// 开启事务
|
||||||
|
template.setEnableTransactionSupport(true);
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载脚本到缓存内
|
||||||
|
*
|
||||||
|
* 默认开启 全局乐观锁 一劳永逸
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public RedisScriptCache loadScripts() {
|
||||||
|
|
||||||
|
RedisScriptCache redisScriptCache = new RedisScriptCache();
|
||||||
|
|
||||||
|
// 拿到state包下 实现了 SystemEventState 接口的,所有子类
|
||||||
|
Set<Class<?>> clazzSet = PackageUtil.listSubClazz(RedisPluginScript.class.getPackage().getName(),
|
||||||
|
true,
|
||||||
|
RedisPluginScript.class
|
||||||
|
);
|
||||||
|
|
||||||
|
for (Class<?> aClass : clazzSet) {
|
||||||
|
// 位运算 去除抽象类
|
||||||
|
if((aClass.getModifiers() & Modifier.ABSTRACT) != 0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过反射 加载所有的 脚本
|
||||||
|
try {
|
||||||
|
RedisPluginScript redisPluginScript = (RedisPluginScript) aClass.newInstance();
|
||||||
|
redisScriptCache.putScript(redisPluginScript);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(RedisMsg.EXCEPTION_REFLEX.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return redisScriptCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package org.opsli.plugins.redis.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.plugins.redis.enums
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-15 14:51
|
||||||
|
* @Description: Redis消息订阅 消息类型
|
||||||
|
*/
|
||||||
|
public enum RedisPushSubMsgType {
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package org.opsli.plugins.redis.exception;
|
||||||
|
|
||||||
|
import org.opsli.common.base.msg.BaseMsg;
|
||||||
|
import org.opsli.common.exception.ServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.plugins.mail.exception
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-14 18:44
|
||||||
|
* @Description: Redis 异常
|
||||||
|
*/
|
||||||
|
public class RedisPluginException extends ServiceException {
|
||||||
|
|
||||||
|
public RedisPluginException(Integer code, String errorMessage) {
|
||||||
|
super(code, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RedisPluginException(BaseMsg msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package org.opsli.plugins.redis.pushsub.entity;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class BaseSubMessage implements RedisPushSubMessage{
|
||||||
|
|
||||||
|
public static final String BASE_TYPE = "TYPE";
|
||||||
|
|
||||||
|
/** 发布订阅频道名称 */
|
||||||
|
protected String channel;
|
||||||
|
|
||||||
|
protected String json;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数 转换json
|
||||||
|
* @param channel 通道
|
||||||
|
* @param type 类型
|
||||||
|
* @param jsonObj 数据
|
||||||
|
*/
|
||||||
|
public void build(String channel, String type, JSONObject jsonObj) {
|
||||||
|
if(channel == null || type == null || jsonObj == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
jsonObj.put(BASE_TYPE, type);
|
||||||
|
this.json = jsonObj.toString();
|
||||||
|
this.channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package org.opsli.plugins.redis.pushsub.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.plugins.redis.entity
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-15 14:50
|
||||||
|
* @Description: Redis 消息订阅
|
||||||
|
*/
|
||||||
|
public interface RedisPushSubMessage extends Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package org.opsli.plugins.redis.pushsub.receiver;
|
||||||
|
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.plugins.redis.receiver
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-15 14:49
|
||||||
|
* @Description: Redis 消息订阅实现基类
|
||||||
|
*/
|
||||||
|
public abstract class BaseReceiver {
|
||||||
|
|
||||||
|
public static final String BASE_CHANNEL = "listener:msg:";
|
||||||
|
private String channel;
|
||||||
|
|
||||||
|
public BaseReceiver(String channel){
|
||||||
|
this.channel = BASE_CHANNEL+channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得监听信道
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getListenerChannel(){
|
||||||
|
return this.channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得消息
|
||||||
|
* @param msg
|
||||||
|
*/
|
||||||
|
public abstract void receiveMessage(String msg);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package org.opsli.plugins.redis.scripts;
|
||||||
|
|
||||||
|
import org.opsli.plugins.redis.scripts.enums.RedisScriptsEnum;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 脚本缓存
|
||||||
|
* @author parker
|
||||||
|
*/
|
||||||
|
public class RedisScriptCache {
|
||||||
|
|
||||||
|
/** 脚本存放容器 */
|
||||||
|
private final ConcurrentMap<RedisScriptsEnum, RedisPluginScript> scriptCacheMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存脚本
|
||||||
|
* @param scriptsEnum 脚本Enum
|
||||||
|
* @return 脚本
|
||||||
|
*/
|
||||||
|
public RedisPluginScript getScript(RedisScriptsEnum scriptsEnum){
|
||||||
|
if(scriptsEnum == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return scriptCacheMap.get(scriptsEnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存脚本
|
||||||
|
* @param redisPluginScript 脚本Enum
|
||||||
|
* @return 脚本
|
||||||
|
*/
|
||||||
|
public boolean putScript(RedisPluginScript redisPluginScript){
|
||||||
|
boolean ret = true;
|
||||||
|
if(redisPluginScript == null || redisPluginScript.getScript() == null || "".equals(redisPluginScript.getScript())
|
||||||
|
|| redisPluginScript.getEnum() == null
|
||||||
|
){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scriptCacheMap.put(redisPluginScript.getEnum(),redisPluginScript);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ret = false;
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package org.opsli.plugins.redis.scripts.enums;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.plugins.redis.enums
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-14 21:56
|
||||||
|
* @Description: Redis 脚本枚举
|
||||||
|
*/
|
||||||
|
public enum RedisScriptsEnum {
|
||||||
|
|
||||||
|
/** Redis加锁脚本 */
|
||||||
|
REDIS_LOCK,
|
||||||
|
/** Redis解锁脚本 */
|
||||||
|
REDIS_UN_LOCK
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue