
使用:
// case 1
@Resource("testService") private RedisClient redisClient; // ... // 省略重写的 redis 方法 // case 2
@Resource("testService") private RedisClusterClient redisClient; // ... // 省略重写的 redis 方法 期望统一成一个:
@Resource("testService") private MyRedisClient redisClient; // ... // 省略重写的 redis 方法 想根据不同配置,MyRedisClient 代理到不同的单例或者集群模式的类。
因为不同环境有的是单点的,要使用 case1 的方式, 有的是 cluster 模式,要使用 case2, 但是这样要切换代码才可以。
想通过配置方式不知道怎么实现,想到可能需要通过代理模式实现,但是具体细节一直没有搞清楚?
Java 动态代理 工厂模式
1 undeflife 2019 年 5 月 26 日 通过配置文件和 @Conditional 方式自动切换 @Conditional(value = { RedisContextHolder.RedisServiceCondition.class }) private RedisClient redisClient; @Conditional(value = { RedisClusterContextHolder.RedisClusterServiceCondition.class }) private RedisClusterClient redisClient; public static class RedisServiceCondition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { context.getEnvironment().getProperty("application.redis") .... return boolean; } } |
2 bxb100 2019 年 5 月 26 日 通过启动参数然后 if else? |
4 undeflife 2019 年 5 月 26 日 上面写得不太对 Conditional 写在类上,这俩 Client 最好有实现相同的接口或父 使用 redis 的地方自动注入即可 |
5 beryl OP @undeflife 因为有个 client 是一个第三方库, 是个接口,rediscluster 是我自己写的。 不太清楚怎么抽象出来一个父类。 另外 Conditional 方法还没用过,在查。每太看明白你上面的示例 thx |
6 xiangyuecn 2019 年 5 月 26 日 interface MyRedisClient{ 定义需要的 redis 功能操作方法 } 根据单点或集群分别实现 MyRedisClient 底层调用逻辑 RedisClient implements MyRedisClient RedisClusterClient implements MyRedisClient 通过配置给 client 动态赋值 private MyRedisClient redisClient=new (RedisClient or RedisClusterClient) 别说我现在用的就是这么干的。。。不过我用 c#写的一套 |
7 beryl OP @xiangyuecn 现在 RedisClient 是个接口,而且是第三方库。所以很难扩展 |
8 tangtj 2019 年 5 月 26 日 可以使用 ApplicationContext 运行时根据配置文件动态获取 bean |
9 xiangyuecn 2019 年 5 月 26 日 @beryl #7 呆板 根据单点或集群分别实现 MyRedisClient 底层调用逻辑 MyXXOO_RedisClient implements MyRedisClient 里面调用了 RedisClient 底层逻辑 MyXXOO_RedisClusterClient implements MyRedisClient 里面调用到了 RedisClusterClient 底层逻辑 通过配置给 client 动态赋值 private MyRedisClient redisClient=new (MyXXOO_RedisClient or MyXXOO_RedisClusterClient) |
10 undeflife 2019 年 5 月 26 日 @beryl 第三方库你同样可以自己再封装一层。 这个场景最合适使用 @Conditional 了 上面的代码我随手写的 有些错漏, 随手收了个例子 你可以看看 https://reflectoring.io/spring-boot-conditionals/ |
11 notreami 2019 年 5 月 26 日 适配模式?门面模式? |
12 beryl OP @undeflife 我看下,不过现在是用的 spring mvc 4.x 支持 @Conditional, 应该有些细微差别。我研究下 |
13 beryl OP |
14 mooncakejs 2019 年 5 月 26 日 via iPhone xml 就很方便了 |
15 codeyung 2019 年 5 月 26 日 多数据源配置 getredis 根据条件传入不同的 redis 实例 你去搜索一下 应该是就改一个 redisService 就好了 |
16 beryl OP @mooncakejs 怎么个方便呢? |
17 undeflife 2019 年 5 月 26 日 @beryl Conditional 会根据条件决定是否创建 bean,所以你只会有一个满足条件的 bean 存在,你使用的地方修改为 by type 而不是默认的 by name 即可 |
18 lihongjie0209 2019 年 5 月 26 日 你直接注入一个 redisServiceFactory 不就好了? |
19 beryl OP @lihongjie0209 现在 cluster 是个 factory, 另一个也是 factory, 尝试封装,一个更高层的 factory, 但是没有成功 |
20 Takamine 2019 年 5 月 26 日 via Android 看到是根据不同的配置,那我就觉得楼上 @Conditional 合适。_(:з」∠)_ |
24 xuanbg 2019 年 5 月 27 日 没明白什么需求,只看到一个集群一个单机的区别。但 Redis 功能上来讲集群和单机并没有什么不同啊?为啥要写两个方法? |
25 yxjn 2019 年 5 月 27 日 spring boot 很简单,只要在配置文件里修改即可。注册的 redistemplate 即是相应的 redis 配置下的。 |
26 palmers 2019 年 5 月 27 日 我理解 lz 的需求是需要动态切换 redis 的数据源, 在向上抽象一个委托类或适配器来执行业务 然后利用观察者模式 或者工厂 bean 来切换 redis 数据源 我觉得这个方法可以办到 |