From f46d9c77e330dbed73f04f1394b8ae4c06ea7cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E7=82=B9?= <2374212111@qq.com> Date: Mon, 17 Jun 2024 17:21:15 +0800 Subject: [PATCH] =?UTF-8?q?[feat]=20=E6=96=B0=E5=A2=9ERedis=E5=A4=9A?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=BA=90=E6=8F=92=E4=BB=B6=20magic-api-plugi?= =?UTF-8?q?n-dynamic-redis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../redis/MagicDynamicRedisAutoConfig.java | 18 ++- .../magicapi/redis/MagicRedisProperties.java | 2 +- .../magicapi/redis/RedisDynamicModule.java | 125 ++---------------- .../magicapi/redis/RedisInstanceFactory.java | 14 +- ...ot.autoconfigure.AutoConfiguration.imports | 3 +- magic-api-plugins/pom.xml | 1 + 6 files changed, 28 insertions(+), 135 deletions(-) diff --git a/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/MagicDynamicRedisAutoConfig.java b/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/MagicDynamicRedisAutoConfig.java index 54d244d2..f5fd55ba 100644 --- a/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/MagicDynamicRedisAutoConfig.java +++ b/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/MagicDynamicRedisAutoConfig.java @@ -4,10 +4,11 @@ package org.ssssssss.magicapi.redis; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.Import; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; @@ -22,14 +23,16 @@ import java.util.Map; @Slf4j @EnableAsync @Configuration -@DependsOn("redisInstanceFactory") @ConfigurationProperties(prefix = "magic-api.redis") -@Import({MagicRedisConfiguration.class,RedisInstanceFactory.class,MagicRedisConfiguration.class}) +@Import({RedisInstanceFactory.class,MagicRedisConfiguration.class,}) public class MagicDynamicRedisAutoConfig implements InitializingBean { @Getter public static String primary; + @Autowired + public RedisInstanceFactory redisInstanceFactory; + @Getter private static Map dynamic = new LinkedHashMap<>(); @@ -37,25 +40,26 @@ public class MagicDynamicRedisAutoConfig implements InitializingBean { public void afterPropertiesSet() { Assert.isNotNull(primary, "Redis未设置默认库"); dynamic.forEach((redisName, redisProperty) -> { - // 构建Redis服务 - RedisInstanceFactory.getInstance().buildRedisTemplate(redisName, redisProperty); + redisInstanceFactory.buildRedisTemplate(redisName, redisProperty); }); log.info("[动态Redis]--共创建Redis[{}]个", dynamic.size()); } @Bean + @ConditionalOnMissingBean public StringRedisTemplate stringRedisTemplate() { MagicRedisProperties redisProperties = dynamic.get(primary); - RedisConnectionFactory connectionFactory = RedisInstanceFactory.getInstance().buildLettuceConnectionFactory(primary, redisProperties); + RedisConnectionFactory connectionFactory = redisInstanceFactory.buildLettuceConnectionFactory(primary, redisProperties); StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(connectionFactory); return template; } @Bean + @ConditionalOnMissingBean public RedisTemplate redisTemplate() { MagicRedisProperties redisProperties = dynamic.get(primary); - RedisConnectionFactory connectionFactory = RedisInstanceFactory.getInstance().buildLettuceConnectionFactory(primary, redisProperties); + RedisConnectionFactory connectionFactory = redisInstanceFactory.buildLettuceConnectionFactory(primary, redisProperties); RedisTemplate template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); return template; diff --git a/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/MagicRedisProperties.java b/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/MagicRedisProperties.java index b685caa2..76983922 100644 --- a/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/MagicRedisProperties.java +++ b/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/MagicRedisProperties.java @@ -21,7 +21,7 @@ public class MagicRedisProperties { /** * 连接类型 */ - private RedisConnectionType type; + private String type; /** * redis主机地址,ip:port,多个用逗号(,)分隔 diff --git a/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/RedisDynamicModule.java b/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/RedisDynamicModule.java index 74b5513d..53f98f20 100644 --- a/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/RedisDynamicModule.java +++ b/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/RedisDynamicModule.java @@ -1,20 +1,8 @@ package org.ssssssss.magicapi.redis; import lombok.extern.slf4j.Slf4j; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.redis.connection.DefaultStringRedisConnection; -import org.springframework.data.redis.connection.RedisConnection; -import org.springframework.data.redis.connection.RedisPipelineException; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.util.ReflectionUtils; import org.ssssssss.magicapi.core.annotation.MagicModule; -import org.ssssssss.magicapi.utils.Assert; -import org.ssssssss.script.functions.DynamicMethod; -import org.ssssssss.script.reflection.JavaReflection; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.*; /** * redis 多数据源插件模块 @@ -23,12 +11,10 @@ import java.util.*; */ @MagicModule("dynamicRedis") @Slf4j -public class RedisDynamicModule implements DynamicMethod { +public class RedisDynamicModule { private final RedisInstanceFactory redisInstanceFactory; - private RedisTemplate redisTemplate; - private boolean isRedisson; public RedisDynamicModule(RedisInstanceFactory redisInstanceFactory) { this.redisInstanceFactory = redisInstanceFactory; @@ -37,110 +23,19 @@ public class RedisDynamicModule implements DynamicMethod { /** * 序列化 */ - public RedisDynamicModule name(String name) { - this.redisTemplate = redisInstanceFactory.getRedisTemplate(name, false); - Assert.isTrue(redisTemplate==null, "当前没有配置redis " + name); - this.isRedisson = Objects.equals("org.redisson.spring.data.connection.RedissonConnectionFactory", this.redisTemplate.getConnectionFactory().getClass().getName()); - return this; - } - - - /** - * 序列化 - */ - private byte[] serializer(Object value) { - if (value == null || value instanceof String) { - return redisTemplate.getStringSerializer().serialize((String) value); + public RedisTemplate of(String name) { + RedisTemplate redisTemplate = redisInstanceFactory.getRedisTemplate(name, true); + if (redisTemplate!=null){ + log.info("使用redis {}", name); + }else { + log.error("当前没有配置redis {}", name); } - return serializer(value.toString()); + return redisTemplate; } - private Object serializerForRedisson(Object value) { - if (value == null || JavaReflection.isPrimitiveAssignableFrom(value.getClass(), value.getClass())) { - return value; - } - return serializer(value.toString()); + public RedisTemplate name(String name) { + return of(name); } - /** - * 反序列化 - */ - @SuppressWarnings("unchecked") - private Object deserialize(Object value) { - if (value != null) { - if (value instanceof byte[]) { - return this.redisTemplate.getStringSerializer().deserialize((byte[]) value); - } - if (value instanceof List) { - List valueList = (List) value; - List resultList = new ArrayList<>(valueList.size()); - for (Object val : valueList) { - resultList.add(deserialize(val)); - } - return resultList; - } - if (value instanceof Map) { - Map map = (Map) value; - LinkedHashMap newMap = new LinkedHashMap<>(map.size()); - map.forEach((key, val) -> newMap.put(deserialize(key), deserialize(val))); - return newMap; - } - } - return value; - } - - /** - * 执行命令 - * - * @param methodName 命令名称 - * @param parameters 命令参数 - */ - @Override - public Object execute(String methodName, List parameters) { - return this.redisTemplate.execute(connection -> { - Object result; - if (isRedisson) { - result = executeForRedisson(((DefaultStringRedisConnection) connection).getDelegate(), methodName, parameters); - } else { - byte[][] params = new byte[parameters.size()][]; - for (int i = 0; i < params.length; i++) { - params[i] = serializer(parameters.get(i)); - } - result = connection.execute(methodName, params); - } - return deserialize(result); - }, isRedisson || this.redisTemplate.isExposeConnection()); - } - - private Object executeForRedisson(RedisConnection connection, String command, List parameters) { - Method[] methods = connection.getClass().getDeclaredMethods(); - for (Method method : methods) { - if (method.getName().equalsIgnoreCase(command) && Modifier.isPublic(method.getModifiers()) && method.getParameterTypes().length == parameters.size()) { - try { - Object ret = this.execute(connection, method, parameters); - if (ret instanceof String) { - return ((String) ret).getBytes(); - } - return ret; - } catch (IllegalArgumentException e) { - if (connection.isPipelined()) { - throw new RedisPipelineException(e); - } - - throw new InvalidDataAccessApiUsageException(e.getMessage(), e); - } - } - } - throw new UnsupportedOperationException(); - } - - private Object execute(RedisConnection connection, Method method, List parameters) { - if (method.getParameterTypes().length > 0 && method.getParameterTypes()[0] == byte[][].class) { - return ReflectionUtils.invokeMethod(method, connection, parameters.stream().map(this::serializer).toArray(byte[][]::new)); - } else if (parameters.size() == 0) { - return ReflectionUtils.invokeMethod(method, connection); - } - return ReflectionUtils.invokeMethod(method, connection, parameters.stream().map(this::serializerForRedisson).toArray()); - } } diff --git a/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/RedisInstanceFactory.java b/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/RedisInstanceFactory.java index a386d144..533f0d8a 100644 --- a/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/RedisInstanceFactory.java +++ b/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/java/org/ssssssss/magicapi/redis/RedisInstanceFactory.java @@ -50,15 +50,7 @@ public class RedisInstanceFactory implements ApplicationContextAware { private static ApplicationContext applicationContext; - private RedisInstanceFactory() { - } - - public static class RedisFactoryLoader { - private static final RedisInstanceFactory INSTANCE = new RedisInstanceFactory(); - } - - public static RedisInstanceFactory getInstance() { - return RedisFactoryLoader.INSTANCE; + public RedisInstanceFactory() { } public RedisTemplate getRedisTemplate(String redisName, boolean isStringRedisTemplate) { @@ -83,7 +75,7 @@ public class RedisInstanceFactory implements ApplicationContextAware { * 创建 ConnectionFactory */ public RedisConnectionFactory buildLettuceConnectionFactory(String redisName, MagicRedisProperties redisProperties) { - String redisClientName = getRedisTemplateName(redisName, false); + String redisClientName = redisName+"RedisConnectionFactory"; if (applicationContext.containsBean(redisClientName)) { return getBean(redisClientName); } @@ -115,7 +107,7 @@ public class RedisInstanceFactory implements ApplicationContextAware { .poolConfig(poolConfig) .build(); LettuceConnectionFactory lettuceConnectionFactory = null; - RedisConnectionType connectionType = redisProperties.getType(); + RedisConnectionType connectionType = RedisConnectionType.match(redisProperties.getType()); if (RedisConnectionType.SENTINEL.equals(connectionType)) { lettuceConnectionFactory = new LettuceConnectionFactory(buildSentinelConfig(redisProperties), clientConfig); } else if (RedisConnectionType.CLUSTER.equals(connectionType)) { diff --git a/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 42df19d1..0f35243d 100644 --- a/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/magic-api-plugins/magic-api-plugin-dynamic-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1,2 @@ -org.ssssssss.magicapi.redis.MagicRedisConfiguration \ No newline at end of file +org.ssssssss.magicapi.redis.RedisInstanceFactory +org.ssssssss.magicapi.redis.MagicDynamicRedisAutoConfig \ No newline at end of file diff --git a/magic-api-plugins/pom.xml b/magic-api-plugins/pom.xml index ce98542e..d85c2608 100644 --- a/magic-api-plugins/pom.xml +++ b/magic-api-plugins/pom.xml @@ -18,6 +18,7 @@ magic-api-plugin-swagger magic-api-plugin-springdoc magic-api-plugin-redis + magic-api-plugin-dynamic-redis magic-api-plugin-mongo magic-api-plugin-elasticsearch magic-api-plugin-cluster