使用:
// 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-05-26 12:41:04 +08:00 2
通过配置文件和 @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-05-26 12:41:40 +08:00
通过启动参数然后 if else?
|
4
undeflife 2019-05-26 12:44:03 +08:00
上面写得不太对 Conditional 写在类上,这俩 Client 最好有实现相同的接口或父
使用 redis 的地方自动注入即可 |
5
beryl OP @undeflife 因为有个 client 是一个第三方库, 是个接口,rediscluster 是我自己写的。 不太清楚怎么抽象出来一个父类。
另外 Conditional 方法还没用过,在查。每太看明白你上面的示例 thx |
6
xiangyuecn 2019-05-26 12:52:41 +08:00
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-05-26 12:57:16 +08:00
可以使用 ApplicationContext 运行时根据配置文件动态获取 bean
|
9
xiangyuecn 2019-05-26 12:57:29 +08:00
@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-05-26 13:01:18 +08:00
@beryl 第三方库你同样可以自己再封装一层。
这个场景最合适使用 @Conditional 了 上面的代码我随手写的 有些错漏, 随手收了个例子 你可以看看 https://reflectoring.io/spring-boot-conditionals/ |
11
notreami 2019-05-26 13:09:28 +08:00
适配模式?门面模式?
|
12
beryl OP @undeflife 我看下,不过现在是用的 spring mvc 4.x 支持 @Conditional, 应该有些细微差别。我研究下
|
13
beryl OP |
14
mooncakejs 2019-05-26 13:14:34 +08:00 via iPhone
xml 就很方便了
|
15
codeyung 2019-05-26 13:14:56 +08:00
多数据源配置 getredis 根据条件传入不同的 redis 实例 你去搜索一下 应该是就改一个 redisService 就好了
|
16
beryl OP @mooncakejs 怎么个方便呢?
|
17
undeflife 2019-05-26 13:45:09 +08:00
@beryl Conditional 会根据条件决定是否创建 bean,所以你只会有一个满足条件的 bean 存在,你使用的地方修改为 by type 而不是默认的 by name 即可
|
18
lihongjie0209 2019-05-26 13:53:14 +08:00
你直接注入一个 redisServiceFactory 不就好了?
|
19
beryl OP @lihongjie0209 现在 cluster 是个 factory, 另一个也是 factory,
尝试封装,一个更高层的 factory, 但是没有成功 |
20
Takamine 2019-05-26 15:45:00 +08:00 via Android
看到是根据不同的配置,那我就觉得楼上 @Conditional 合适。_(:з」∠)_
|
24
xuanbg 2019-05-27 07:46:36 +08:00
没明白什么需求,只看到一个集群一个单机的区别。但 Redis 功能上来讲集群和单机并没有什么不同啊?为啥要写两个方法?
|
25
yxjn 2019-05-27 10:50:55 +08:00
spring boot 很简单,只要在配置文件里修改即可。注册的 redistemplate 即是相应的 redis 配置下的。
|
26
palmers 2019-05-27 11:48:49 +08:00
我理解 lz 的需求是需要动态切换 redis 的数据源, 在向上抽象一个委托类或适配器来执行业务 然后利用观察者模式 或者工厂 bean 来切换 redis 数据源 我觉得这个方法可以办到
|