Quarkus中为RedisClient添加无实现类委托的装饰器可行吗?
实现无委托类的RedisClient装饰器方案
可以实现无自定义实现类的装饰器,核心是利用动态代理或框架自带的代理机制包裹RedisClient实例,无需手写委托类。以下是具体实现方案(以Java/Spring环境为例):
1. 基于JDK动态代理(适用于接口类型的RedisClient)
如果你的RedisClient是接口(比如Spring Data Redis的RedisOperations或自定义RedisClient接口),直接用JDK动态代理即可:
代理处理器代码
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class RedisClientProxyHandler implements InvocationHandler { private final Object target; public RedisClientProxyHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 调用前补充信息 System.out.printf("Redis调用前置:方法=%s,参数=%s%n", method.getName(), args); // 执行原RedisClient方法 Object result = method.invoke(target, args); // 调用后补充信息 System.out.printf("Redis调用后置:方法=%s,返回结果=%s%n", method.getName(), result); return result; } // 生成代理实例的工具方法 @SuppressWarnings("unchecked") public static <T> T createProxy(T target) { return (T) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new RedisClientProxyHandler(target) ); } }
使用方式
获取RedisClient实例后,用代理类包裹:
// 原RedisClient实例 RedisClient rawClient = getRedisClient(); // 生成代理后的实例 RedisClient proxiedClient = RedisClientProxyHandler.createProxy(rawClient); // 后续所有调用都用proxiedClient,装饰逻辑会自动触发 proxiedClient.set("user:1", "Tom");
2. 基于CGLIB代理(适用于非接口的RedisClient实现类)
如果RedisClient是具体类而非接口,用CGLIB动态代理(需引入CGLIB依赖):
代理拦截器代码
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class RedisClientCglibProxy implements MethodInterceptor { private final Object target; public RedisClientCglibProxy(Object target) { this.target = target; } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { // 前置装饰逻辑 System.out.printf("Redis调用前置(CGLIB):方法=%s,参数=%s%n", method.getName(), args); // 执行原方法 Object result = proxy.invokeSuper(obj, args); // 后置装饰逻辑 System.out.printf("Redis调用后置(CGLIB):方法=%s,返回结果=%s%n", method.getName(), result); return result; } // 生成代理实例的工具方法 @SuppressWarnings("unchecked") public static <T> T createProxy(T target) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(new RedisClientCglibProxy(target)); return (T) enhancer.create(); } }
使用方式
和JDK代理一致,替换为CGLIB的工具方法即可:
RedisClient proxiedClient = RedisClientCglibProxy.createProxy(rawClient); proxiedClient.get("user:1");
3. 装饰器未触发的常见排查点
- 未使用代理实例:你可能仍在调用原始RedisClient对象,务必确保所有操作都使用代理后的实例。
- 代理类型不匹配:接口类用JDK代理,具体类必须用CGLIB,否则无法生成有效代理。
- 方法被final修饰:CGLIB无法代理final方法,若RedisClient的核心方法是final,需更换代理方式或调整方法修饰符。
4. Spring环境下的优雅实现(自动代理)
如果是Spring项目,可通过BeanPostProcessor自动为所有RedisClient实例生成代理,无需手动包裹:
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Component; @Component public class RedisClientProxyProcessor implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { // 匹配RedisClient类型的Bean,自动生成代理 if (bean instanceof RedisClient) { return RedisClientProxyHandler.createProxy((RedisClient) bean); } return bean; } }
配置后,Spring容器中所有RedisClient实例都会被自动代理,原有调用代码无需修改。
内容的提问来源于stack exchange,提问作者sg2000
相关产品推荐
相关产品推荐

