Răsfoiți Sursa

修复redis模块不支持redisson部分命令的问题

jmxd 2 ani în urmă
părinte
comite
d59411b386

+ 0 - 5
magic-api-plugins/magic-api-plugin-redis/pom.xml

@@ -17,10 +17,5 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.redisson</groupId>
-            <artifactId>redisson-spring-data-23</artifactId>
-            <version>3.15.6</version>
-        </dependency>
     </dependencies>
 </project>

+ 62 - 8
magic-api-plugins/magic-api-plugin-redis/src/main/java/org/ssssssss/magicapi/redis/RedisModule.java

@@ -1,11 +1,18 @@
 package org.ssssssss.magicapi.redis;
 
+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.RedisConnectionFactory;
-import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.connection.RedisPipelineException;
 import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.util.ReflectionUtils;
 import org.ssssssss.magicapi.core.annotation.MagicModule;
 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.*;
 
 /**
@@ -18,8 +25,11 @@ public class RedisModule implements DynamicMethod {
 
 	private final StringRedisTemplate redisTemplate;
 
+	private final boolean isRedisson;
+
 	public RedisModule(RedisConnectionFactory connectionFactory) {
 		this.redisTemplate = new StringRedisTemplate(connectionFactory);
+		this.isRedisson = Objects.equals("org.redisson.spring.data.connection.RedissonConnectionFactory", this.redisTemplate.getConnectionFactory().getClass().getName());
 	}
 
 	/**
@@ -32,6 +42,13 @@ public class RedisModule implements DynamicMethod {
 		return serializer(value.toString());
 	}
 
+	private Object serializerForRedisson(Object value){
+		if(value == null || JavaReflection.isPrimitiveAssignableFrom(value.getClass(), value.getClass())){
+			return value;
+		}
+		return serializer(value.toString());
+	}
+
 	/**
 	 * 反序列化
 	 */
@@ -49,7 +66,7 @@ public class RedisModule implements DynamicMethod {
 				}
 				return resultList;
 			}
-			if(value instanceof Map){
+			if (value instanceof Map) {
 				Map<Object, Object> map = (Map<Object, Object>) value;
 				LinkedHashMap<Object, Object> newMap = new LinkedHashMap<>(map.size());
 				map.forEach((key, val) -> newMap.put(deserialize(key), deserialize(val)));
@@ -67,12 +84,49 @@ public class RedisModule implements DynamicMethod {
 	 */
 	@Override
 	public Object execute(String methodName, List<Object> parameters) {
-		return this.redisTemplate.execute((RedisCallback<Object>) connection -> {
-			byte[][] params = new byte[parameters.size()][];
-			for (int i = 0; i < params.length; i++) {
-				params[i] = serializer(parameters.get(i));
+		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(connection.execute(methodName, params));
-		});
+			return deserialize(result);
+		}, isRedisson || this.redisTemplate.isExposeConnection());
 	}
+
+	private Object executeForRedisson(RedisConnection connection, String command, List<Object> 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<Object> 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());
+	}
+
 }