java 自动转 golang_基于dubbo-go的golang与java通信解决方案实践——伍:golang代码的生成...

golang代码生成方案

为了更加贴合java开发的习惯,我自己开发了maven plugin,解析java代码并自动生成go代码,以及通过git submodule拉取golang的lib库,生成go代码后再推送至lib库上。

golang代码的格式设计

格式设计我按照java的开发习惯来,部分参考了protobuf的规定。

单独一个服务的结构如下:7e084144ac409e4a9e2f318170946e59.pnggolang代码结构

其中dto为使用的数据结构,enums中为简单枚举,service里则是调用方法。我将dubbo-go提供的调用方式进行了封装,以贴合更加常用的调用方法:82a15455bf3c44f9c86143639b22df1e.pngOrderRpcService

可以看到,用户在使用方法时直接调用GetOrder(arg0 int64)方法即可,而不用关心默认方法里的参数内容,更加方便使用。

但是这样设计的格式有个问题:自己魔改的dubbo-go版本是在lib库springboot-dubbo-go的下一层,但是想要能够装配接口名与Url,必须先执行service中的config.SetConsumerService方法。因为这个问题,一度我将整个服务发现的过程迁移到了lib库中,但最终考虑到扩展多个lib库的情况,采用了以下措施:

0758d3dc9abcc121e1773b07897d2e9a.pngclient.go

新增了一个client文件,在这里初始化时调用nacos_client的Init方法,同时引用api包,即自动生成的golang代码所在的包,以此来保证api包中的init方法在nacos_client的Init方法被调用之前就调用了。

java的泛型嵌套与重载

java有一些特性是golang所不支持的,比如泛型嵌套和重载。

泛型嵌套

我开发的代码生成插件中,支持的java泛型只有Map与List。从go请求java时,go将数据变为[]interface{},而java返回时,go如何以怎样的数据结构接收成了设计上的一个问题。使用[]interface{}接收的话,插件开发简单,但用户使用需要显式转换类型成本更高,使用数组的话则会碰到与Map一样的问题,java的泛型嵌套无法传递数据:比如List>是无法传递到[][]int32上的。在与同事咨询了他们protobuf的开发过程后了解到,他们是不会使用泛型嵌套的。因而我也采用了相同的方案:将List转换为数组并且不支持泛型嵌套。

重载

golang是不支持重载的,所以我在插件中进行了判断:如果service中存在重载方法,则跳过此service的生成。

其他

java中有一些特殊的类,比如LocalDatetime,官方没有提供其对于golang中time.Time的转换,所以遇到这种类我也直接跳过不生成dto及相关的service。

Maven插件的开发

maven插件开发相关可以移步至我的《maven插件开发》文章中查看。

结语

其实一开始决定要自己做这么个解决方案的时候还是很忐忑的,实际开发中的各种困难也确实证明了我的顾虑:没有接触过golang,需要一边百度一边请教同事来开发/阅读源码;没有开发过maven,遇到了不少插件开发的难题;dubbo-go遇到的2个bug我花了十多天才找到原因并进行处理,等等。好在结局不错,在开发的过程中也收获了不少。在此将实践经验进行了整理与分享,希望能够帮助更多的人。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值