60

Go-Spring : Another Go Style!

 4 years ago
source link: https://www.tuicool.com/articles/26viIfY
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Go-Spring 是模仿 Java 的 Spring 全家桶实现的一套 GoLang 的应用程序框架,仍然遵循“习惯优于配置”的原则,提供了依赖注入、自动配置、开箱即用、丰富的第三方类库集成等功能,能够让程序员少写很多的样板代码。

1.

前言

去年年底的时候,我所在的团队由于业务调整,技术栈也随之发生改变,由之前的 PHP +Java 变成了 Golang + Java。初次接触 Golang,颇不适应,首先就是它那不同一般的语法,然后是没有一个成熟好用的开发框架。语法问题时间长了代码写的多了也就慢慢适应了,但是没有顺手的开发框架就太影响开发效率和代码质量了,作为一个资深的 Java + Spring 全家桶开发者,我希望能改变这一现状。经过一段时间的使用和探索,我发现完全可以搞出一套像 Spring 全家桶(Spring Framework + Spring Boot +Spring Cloud)那样的解决方案出来!

Spring 全家桶在 Java 世界的地位自然无需多言,它不仅为 Java 开发者证明了基于注解开发、基于 AOP 开发以及面向接口开发能够给程序带来极大的灵活性,更重要的是带来了依赖注入、声明式事务、统一的异常处理、模块自动化加载、更简单的 Maven 管理、更简单的单元测试等优秀的开发实践。

但是 GoLang 和 Java 毕竟不同,我为什么笃信自己肯定能搞出来呢?要回答这个问题,实际上是在回答另一个问题,即 Java 的哪些语言特性支撑了 Spring 全家桶能够实现那些核心能力,而 GoLang 又有哪些相似的语言特性?

追根溯源,Java 的字节码、反射、注解、包扫描等机制支撑了 Spring 全家桶能够实现 AOP 开发、依赖注入、声明式事务、模块自动化加载等核心特性。GoLang 因为没有字节码,所以不能实现 AOP 。但是 GoLang 有 Tags、Reflection、_ Imports、init() 机制,所以尽管实现起来不一定有 Java 优雅,但是也能实现依赖注入、模块自动化加载这些 Spring 全家桶的最核心特性。而且,尽管 GoLang 无法实现 AOP,但是也可以通过 Middleware 实现同样的功能。

经过一番探索和实践,终于 Go-Spring 诞生了!在我的眼中,Go-Spring 和 GoLang 本身一样,一出生就带着叛逆和创新精神,GoLang 以不同于主流编程语言语法的姿态出现,而 Go-Spring 则在质疑中以面向接口和依赖注入等多种绝对 Java 的特性出现在大家眼前。

2.

特性

Go-Spring 是模仿 Java 的 Spring 全家桶实现的一套 GoLang 的应用程序框架,仍然遵循“习惯优于配置”的原则,提供了依赖注入、自动配置、开箱即用、丰富的第三方类库集成等功能,能够让程序员少写很多的样板代码。总结起来,Go-Spring 至少有以下五大特点:

▍可扩展的启动器框架,帮你优雅的组织代码

下面这张图展示了一个 rtmp 服务器的启动函数,这里只截取了其中的一部分,可以看到启动函数的代码太长了,而且需要精心组织才能保证代码的可读性。

YRrmYvu.png!web

而使用 Go-Spring 的启动器框架则可以把这些启动过程封装到单独的文件中,使得功能更内聚,代码更清晰。下图展示的就是一个封装好的启动文件。

Uziy6bF.png!web

在使用了 Go-Spring 的启动器框架之后,程序的启动过程就变成了非常简单的一行代码了!

JFFfaiI.png!web

▍面向接口+依赖注入,灵活替换实现方案

Go-Spring 为 Redis 服务提供了统一的 API 接口,但是底层实现却有多种方案。用户在使用 Redis 服务编写业务代码时只需要关注 API 接口,而不需要关心底层采用的是哪种方案。

zY3yeeQ.png!web

当然用户最终会选择一个 redis 服务的底层实现,而引入这个实现仅仅只需要一行代码即可!

7j2qyyz.png!web

如果你想换成其他的 redis 底层实现,也仅仅是一行代码的事。

UBfaUnI.png!web

▍自动绑定配置项,简化配置文件使用

在使用了 Go-Spring 的代码中只需要为变量设置好要绑定的配置项的名称,并在配置文件中添加该配置项,Go-Spring 就会自动帮你完成变量和配置项的绑定工作。

7fiaa2E.png!web

Go-Spring 还支持按照运行环境绑定不同的配置文件,比如当检测到线下环境时 Go-Spring 使用 application-test.properties 配置文件,而当检测到线上环境时会使用 application-online.properties 配置文件。

yUZFzqR.png!web

▍有效地帮助做好项目的依赖管理

Go-Spring 为每一个模块都提供了一个抽象接口,使用者不需要关心接口内部是怎么实现的,这样能非常容易的解决依赖升级的问题。Go-Spring 保证已发布的所有版本的项目依赖都是正确的,而且 Go-Spring 每发布一个版本都会对依赖进行升级,这样使用者只需要关注 Go-Spring 的版本变化,就能享受到其他依赖自动升级的好处!

▍让复杂的单元测试变得更简单

GoLang 的单元测试尤其对 http 的单元测试简直烂的要命!使用 Go-Spring 启动的项目能够在单元测试的时候使用真实的项目运行环境,而不是使用一个 fake 的 http 环境。

3.

组件

Go-Spring 包含了四个核心项目,其中

JFjYB3E.png!web

go-spring 实现了 IoC 容器和依赖注入等核心功能;

go-spring-boot 提供了自动配置及应用程序的启动框架;

go-spring-cloud 立足开源世界打造人人可用的微服务框架;

go-spring-didi 聚焦滴滴内部技术实现具有滴滴特点的微服务框架。

4.

示例

下面我将通过一个最简单的 http 服务为大家展示如何使用 Go-Spring。

  1. 新建 main.go 文件,创建启动程序,并且指定配置文件所在目录。

q67vUby.png!web

  1. 在程序中引入 echo http 服务。

bAbIFnA.png!web

  1. 新建 example.go 文件,实现一个示例服务,并且在 InitController() 函数中注册 http 接口的路由。

aQvMraE.png!web

  1. 将一个示例服务的对象注册到 Go-Spring 的 IoC 容器里,这样 Go-Spring 就能自动地加载用户注册的 http 接口的路由。

7viaAvq.png!web

  1. 在 main.go 文件中引入示例服务所在的包,这样 Go-Spring 框架在启动的时候就能加载示例服务所在的模块。

aE7nE3V.png!web

通过上面的 5 个步骤我们就得到了一个简单但完整的 http 服务,使用 go run main.go 命令启动程序,并使用 curl http://localhost :8080/ 进行测试,可以看到请求的返回结果如下:

{"code":900001,"msg":"biz error"}

OK,是不是已经开始感觉到 Go-Spring 的威力了!下面我们再来看一下使用了 Go-Spring 框架的项目的单元测试会怎么写。

首先,我们可以编写一个 TestMain 函数用于启动真实的 http 服务器。

yABf6fU.png!web

实际上图展示的代码还可以更精简,精简为一行。

然后,我们可以编写一个测试函数发送真实的 http 请求,也不需要 fake 或者 mock。

ri6nMjY.png!web

执行这个单元测试,你就会发现,你得到了一个完全不用 mock 和 fake ,并且功能完整、可以断点调试的测试环境。

5.

总结

除了上面展示的能够创建 http 服务和单元测试之外,Go-Spring 已经支持了 mysql 服务、redis 服务、kafka 服务、ddmq服务、服务注册和服务发现服务以及多种 rpc 服务,并且更多的新组件和新特性正在源源不断的通过滴滴内源加入进来,未来 Go-Spring 会变得越来越完善,越来越好用!

Another Go Style!我个人认为 Go-Spring 代表了一种新的编程模式,甚至是一种新的生产力方式,我希望大家在使用 Go-Spring 的过程中能够解放思想,提高效率,得到更多的快乐和自由,也多留一些时间给朋友和家人!

本文首发自普惠出行产品技术 (ID:pzcxtech)

ARbAfuN.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK