From 779a0126e5951558a9e31510110eac3fa9660275 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 10 Apr 2024 14:24:50 +0200 Subject: [PATCH] Polishing. Avoid duplicate method lookup by keeping reference to Method. Add missing native image hints for command proxies. Original Pull Request: #2887 --- .../data/redis/aot/RedisRuntimeHints.java | 24 +++++++++++++++++++ .../data/redis/core/RedisConnectionUtils.java | 15 ++++++------ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/springframework/data/redis/aot/RedisRuntimeHints.java b/src/main/java/org/springframework/data/redis/aot/RedisRuntimeHints.java index d5b122410..0649d513e 100644 --- a/src/main/java/org/springframework/data/redis/aot/RedisRuntimeHints.java +++ b/src/main/java/org/springframework/data/redis/aot/RedisRuntimeHints.java @@ -35,6 +35,7 @@ import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFa import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.*; import org.springframework.data.redis.core.*; +import org.springframework.data.redis.core.RedisConnectionUtils.RedisConnectionProxy; import org.springframework.data.redis.core.convert.KeyspaceConfiguration; import org.springframework.data.redis.core.convert.MappingConfiguration; import org.springframework.data.redis.core.convert.MappingRedisConverter; @@ -157,6 +158,20 @@ public class RedisRuntimeHints implements RuntimeHintsRegistrar { boundOperationsProxy(BoundStreamOperations.class, classLoader, hints); boundOperationsProxy(BoundValueOperations.class, classLoader, hints); boundOperationsProxy(BoundZSetOperations.class, classLoader, hints); + + // Connection Splitting + registerRedisConnectionProxy(TypeReference.of(RedisCommands.class), hints); + registerRedisConnectionProxy(TypeReference.of(RedisGeoCommands.class), hints); + registerRedisConnectionProxy(TypeReference.of(RedisHashCommands.class), hints); + registerRedisConnectionProxy(TypeReference.of(RedisHyperLogLogCommands.class), hints); + registerRedisConnectionProxy(TypeReference.of(RedisKeyCommands.class), hints); + registerRedisConnectionProxy(TypeReference.of(RedisListCommands.class), hints); + registerRedisConnectionProxy(TypeReference.of(RedisSetCommands.class), hints); + registerRedisConnectionProxy(TypeReference.of(RedisScriptingCommands.class), hints); + registerRedisConnectionProxy(TypeReference.of(RedisServerCommands.class), hints); + registerRedisConnectionProxy(TypeReference.of(RedisStreamCommands.class), hints); + registerRedisConnectionProxy(TypeReference.of(RedisStringCommands.class), hints); + registerRedisConnectionProxy(TypeReference.of(RedisZSetCommands.class), hints); } static void boundOperationsProxy(Class type, ClassLoader classLoader, RuntimeHints hints) { @@ -179,4 +194,13 @@ public class RedisRuntimeHints implements RuntimeHintsRegistrar { TypeReference.of("org.springframework.aop.framework.Advised"), // TypeReference.of("org.springframework.core.DecoratingProxy")); } + + static void registerRedisConnectionProxy(TypeReference typeReference, RuntimeHints hints) { + + hints.proxies().registerJdkProxy(TypeReference.of(RedisConnectionProxy.class), // + typeReference, // + TypeReference.of("org.springframework.aop.SpringProxy"), // + TypeReference.of("org.springframework.aop.framework.Advised"), // + TypeReference.of("org.springframework.core.DecoratingProxy")); + } } diff --git a/src/main/java/org/springframework/data/redis/core/RedisConnectionUtils.java b/src/main/java/org/springframework/data/redis/core/RedisConnectionUtils.java index 87c739a8d..20e4954ae 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisConnectionUtils.java +++ b/src/main/java/org/springframework/data/redis/core/RedisConnectionUtils.java @@ -33,7 +33,6 @@ import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; /** * Helper class that provides static methods for obtaining {@link RedisConnection} from a @@ -451,16 +450,16 @@ public abstract class RedisConnectionUtils { static class ConnectionSplittingInterceptor implements MethodInterceptor { private final RedisConnectionFactory factory; - private final @Nullable String commandInterface; + private final @Nullable Method commandInterfaceMethod; public ConnectionSplittingInterceptor(RedisConnectionFactory factory) { this.factory = factory; - this.commandInterface = null; + this.commandInterfaceMethod = null; } - public ConnectionSplittingInterceptor(RedisConnectionFactory factory, String commandInterface) { + private ConnectionSplittingInterceptor(RedisConnectionFactory factory, Method commandInterfaceMethod) { this.factory = factory; - this.commandInterface = commandInterface; + this.commandInterfaceMethod = commandInterfaceMethod; } @Override @@ -484,7 +483,7 @@ public abstract class RedisConnectionUtils { ProxyFactory proxyFactory = new ProxyFactory(ReflectionUtils.invokeMethod(method, obj)); - proxyFactory.addAdvice(new ConnectionSplittingInterceptor(factory, method.getName())); + proxyFactory.addAdvice(new ConnectionSplittingInterceptor(factory, method)); proxyFactory.addInterface(RedisConnectionProxy.class); proxyFactory.addInterface(returnType); @@ -510,8 +509,8 @@ public abstract class RedisConnectionUtils { Object target = connection; try { - if (StringUtils.hasText(commandInterface)) { - target = ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(RedisConnection.class, commandInterface), + if (commandInterfaceMethod != null) { + target = ReflectionUtils.invokeMethod(commandInterfaceMethod, connection); }