多年前曾经梦想着能有一天能在 Go 语言中使用上 Spring 那样强大的框架,幸运的是我找到了go-spring,一款类似 Spring 的库,我很喜欢它,并且在我的项目中深度使用它,它给我带来了非常酷的编程体验。
然而很不幸的是最近 go-spring 停止更新了(最近的一次提交停留在九个月之前),一些问题无法得到有效的解决,因此我决定创建一个基于 go-spring 的开源库,我为它修复了一系列 bug ,并添加了一些新得特性,并对代码结构进行了简化,将外部生态从核心库中移除,仅保留核心功能,外部生态预计将来将作为独立的仓库存在,我将持续继续将它维护下去,也希望有感兴趣的人可以一起参与进来一起持续开发它。
仓库地址: https://github.com/go-spring-projects/go-spring
允许在运行时动态刷新属性,不仅支持基本数据类型,还支持结构、切片和 Map 类型。
package main
import (
"fmt"
"log/slog"
"net/http"
"github.com/go-spring-projects/go-spring/dync"
"github.com/go-spring-projects/go-spring/gs"
)
type Handler struct {
Open dync.Bool `value:"${server.open:=true}"`
}
func (h *Handler) OnInit(ctx gs.Context) error {
http.HandleFunc("/server/status", func(writer http.ResponseWriter, request *http.Request) {
if !h.Open.Value() {
http.Error(writer, "server closed", http.StatusNotAcceptable)
return
}
fmt.Fprint(writer, "server running")
})
return nil
}
type Server struct {
Logger *slog.Logger `logger:""`
}
func (s *Server) OnInit(ctx gs.Context) error {
props := ctx.(gs.Container).Properties()
http.HandleFunc("/server/status/open", func(writer http.ResponseWriter, request *http.Request) {
props.Set("server.open", "true")
s.Logger.Info("server opened")
})
http.HandleFunc("/server/status/close", func(writer http.ResponseWriter, request *http.Request) {
props.Set("server.open", "false")
s.Logger.Info("server closed")
})
go func() {
http.ListenAndServe(":7878", nil)
}()
return nil
}
func main() {
gs.Object(new(Handler))
gs.Object(new(Server))
if err := gs.Run(); nil != err {
panic(err)
}
}
// Output:
//
// $ curl http://127.0.0.1:7878/server/status
// server running
//
// $ curl http://127.0.0.1:7878/server/status/close
//
// $ curl http://127.0.0.1:7878/server/status
// server closed
//
// $ curl http://127.0.0.1:7878/server/status/open
//
// $ curl http://127.0.0.1:7878/server/status
// server running
Go-Spring
允许您注册自定义值验证器。如果值验证失败,则Go-Spring
将在启动阶段报告一个错误。
在这例子中, 我们将使用 go-validator/validator, 您可以参考这个示例来注册您的自定义验证器。
package main
import (
"fmt"
"log/slog"
"github.com/go-spring-projects/go-spring/conf"
"github.com/go-spring-projects/go-spring/gs"
"gopkg.in/validator.v2"
)
const validatorTagName = "validate"
type validatorWrapper struct {
validator *validator.Validator
}
func (v *validatorWrapper) Field(tag string, i interface{}) error {
if 0 == len(tag) {
return nil
}
return v.validator.Valid(i, tag)
}
func init() {
conf.Register(validatorTagName, &validatorWrapper{validator: validator.NewValidator().WithTag(validatorTagName)})
}
//--------------------------------------------------------------------------
type DBOptions struct {
UserName string `value:"${username}"`
Password string `value:"${password}"`
IP string `value:"${ip}"`
Port int32 `value:"${port}" validate:"min=1024,max=65535"`
DB string `value:"${db}" validate:"nonzero"`
}
type MysqlDatabase struct {
Logger *slog.Logger `logger:""`
Options DBOptions `value:"${db}"`
}
func (md *MysqlDatabase) OnInit(ctx gs.Context) error {
md.Logger.Info("mysql connection summary",
"url", fmt.Sprintf("mysql://%s:%s@%s:%d/%s", md.Options.UserName, md.Options.Password, md.Options.IP, md.Options.Port, md.Options.DB))
return nil
}
func main() {
gs.Property("db.username", "admin")
gs.Property("db.password", "123456")
gs.Property("db.ip", "127.0.0.1")
gs.Property("db.port", "0") // set db.port=0
gs.Property("db.db", "test")
gs.Object(new(MysqlDatabase))
if err := gs.Run(); nil != err {
panic(err)
}
}
//
// Output:
// panic: container refresh failed
// ↳object bean "main/main.MysqlDatabase:MysqlDatabase" /projects/go-project/gocase/validator/main.go:58
// ↳bind MysqlDatabase.Options error: validate MysqlDatabase.Options.Port error: less than min
更多特性请参考说明: go-spring-projects/go-spring
最后还要感谢原作者lvan100的辛勤付出。
101
FightPig 2023-11-03 17:26:46 +08:00
@kirito41dd 没事,rust on spring 估计后面也有人搞🐶
|
103
franktopplus 2023-11-03 18:12:35 +08:00 via Android
真没有必要,每个语言有各自的范式。java 需要依赖注入,可以理解为特性,也可理解为缺点
|
104
BBCCBB 2023-11-03 18:19:15 +08:00
spring 是非常轻量的. 但你项目复杂了引入了各种中间件, 框架. 这就不能怪到 spring 身上了.
不管什么语言, 项目复杂后能轻量就怪了 |
105
Leviathann 2023-11-03 18:23:42 +08:00 1
你知道 bean 为什么叫 bean 吗?
java 是咖啡的意思,bean 是豆子,也就是咖啡豆,咖啡豆组成咖啡 而 jar 是罐子也就是咖啡豆的罐子 这些词完全都是语义化的,被挪用到其他语言显得格外幽默 好像很多人不知道编程语言首先是一种语言? |
106
edisonwong 2023-11-03 18:26:16 +08:00
1. op 牛逼,付出努力,实现并开源,存在即合理
2. 看到楼上的回复崩不住了😂,gava ? 或许未来再来个 gomcat ? 😂 |
107
potatowish 2023-11-03 18:38:05 +08:00 via iPhone 1
|
108
Rorysky 2023-11-03 22:41:48 +08:00
真的没必要,就让 spring 留在 java 生态吧
|
110
sgwk 2023-11-04 09:09:02 +08:00
用 go ,主要是为了方便,轻快,去除 spring 那套。
|
111
ikas 2023-11-04 11:17:41 +08:00
时代变了.连 spring 的思维都没人想着去理解了
|