Spring boot 2.1 + Dubbo 2.7.1 实现分组聚合

 

  • 分组聚合使用场景

官网:比如菜单服务,接口一样,但有多种实现,用group区分,现在消费方需从每种group中调用一次返回结果,合并结果返回,这样就可以实现聚合菜单项。

自己理解:接口一样,不同的实现,可以将 不同的服务用 group 区分,调用的时候指定 group ,就能获取对应服务的结果

  • 遇到的问题

在用 spring mvc 整合 dubbo 做分组聚合的时候配置如下

 

服务提供者

<bean id="mergeService" class="com.truthso.monitor.image.service.CompareServiceImpl"/>

<dubbo:service group="merge1" interface="com.truthso.monitor.image.service.CompareService" ref="mergeService"/>

<bean id="mergeService2" class="com.truthso.monitor.image.service.CompareServiceImpl2"/>

<dubbo:service group="merge2" interface="com.truthso.monitor.image.service.CompareService" ref="mergeService2"/>

 有一个抽象接口 CompareService 两个接口实现 mergeService 分组为 merge1; mergeService2 分组为 merge2

服务消费者

<dubbo:reference id="mergeService" interface="com.truthso.monitor.image.service.CompareService" group="*" merger="true"/>

指定 group 为 *,merger 为 true 

这样在调用的时候只需要普通的调用,方法返回的结果里面是两个实现的结果

@Controller
@RequestMapping("/index")
public class IndexController {

    @Autowired
    CompareService compareService;

    @RequestMapping("home")
    @ResponseBody
    public String home() {
        List<String> result = compareService.mergeResult();
        System.out.println(result);
        return "OK";
    }

}

但是在 Spring boot 里面使用注解的方式 @Reference 有参数 group 并没有参数  merge,使用的时候,只能调用到一个接口实现的结果

@RestController
public class DemoController {

    private static final Logger logger = LoggerFactory.getLogger(DemoController.class);

    @Reference(version = "1.0.0", group = "*")
    private DemoService demoService;

    @RequestMapping("/hello/{name}")
    public String sayHello(@PathVariable String name) {
        List<Integer> list = demoService.getAll();
        System.out.println(list);
        // String str = demoService.sayHello(name);
        return "mother fucker";
    }

}
  • 解决过程

想着没有就给你加一个好了,就重写了一个 一样的  Reference 在最后面加上了代码 merger

String merger() default "true";

用 String 的 原因是在 org.apache.dubbo.config.AbstractMethodConfig 里面的 merger 也是 String 的

但是还是不生效,只能跟踪源码,注解的方式不外乎启动的时候扫描,然后反射获取一些属性,后面再拼装成连接 bubbo 的URL,所以追踪到 org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceBeanBuilder 这个类应该就是组装类似<dubbo:reference> 标签的类,在 preConfigureBean 里面 最后一行 

// 在第 134 行
// Bind annotation attributes
dataBinder.bind(new AnnotationPropertyValuesAdapter(reference, applicationContext.getEnvironment(), IGNORE_FIELD_NAMES));

发现有bind参数的动作,发现在  org.apache.dubbo.config.spring.beans.factory.annotation.AnnotationPropertyValuesAdapter 57 行处有  getAttributes(annotation, propertyResolver, ignoreDefaultValue, ignoreAttributeNames) ,所以在 org.apache.dubbo.config.spring.util.AnnotationUtils.getAttributes 处发现代码

// 252 行
// ignore default attribute value
if (ignoreDefaultValue && nullSafeEquals(attributeValue, getDefaultValue(annotation, attributeName))) {
    continue;
}

原来默认有值的参数被continue了,所以将自己设置的 merger 的默认值改为 "" 空串后,就能正常调用了.

  • 总结
    • 不清楚为什么默认有值的属性就continue了
    • 不知道为啥这个注解不把 merger 加上呢,是出于什么考虑呢
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值