前言
多年前曾经梦想着能有一天能在 Go 语言中使用上 Spring 那样强大的框架,幸运的是我找到了go-spring,一款类似 Spring 的库,我很喜欢它,并且在我的项目中深度使用它,它给我带来了非常酷的编程体验。
然而很不幸的是最近 go-spring 停止更新了(最近的一次提交停留在九个月之前),一些问题无法得到有效的解决,因此我决定创建一个基于 go-spring 的开源库,我为它修复了一系列 bug ,并添加了一些新得特性,并对代码结构进行了简化,将外部生态从核心库中移除,仅保留核心功能,外部生态预计将来将作为独立的仓库存在,我将持续继续将它维护下去,也希望有感兴趣的人可以一起参与进来一起持续开发它。
仓库地址: https://github.com/go-spring-projects/go-spring
特性
- IoC 容器: 实现了基于反射的控制反转(IoC)容器,支持结构体、函数和常量的注入。这意味着你可以使用' autowired '标签来自动注入依赖,而不必手动管理它们。
- 配置管理: 受 Spring 的 @Value 注释的启发,Go-Spring 允许您从多个源(如环境变量、文件、命令行参数等)获取配置项。这为配置管理带来了前所未有的灵活性。
- 配置验证器: 通过支持自定义验证器扩展扩展了其健壮的配置管理功能。这使您能够对属性执行有效性检查,确保仅将有效的配置应用于您的应用程序。
- 结构化日志: 使用标准库 slog 提供内置日志记录器支持,以实现有效和简化的日志记录。这种增强提供了清晰、简洁和结构良好的日志信息,有助于系统调试和性能监视。
- 动态属性: 提供动态属性刷新功能,让您无需重新启动应用程序即可动态更新应用程序属性。它满足了需要高可用性和实时响应的应用程序的需求。
- 依赖序事件: 按照 bean 依赖关系的顺序,确保根据对象的生命周期正确通知初始化和销毁事件。这增强了系统在其生命周期运行中的鲁棒性和可靠性。
动态属性例子
允许在运行时动态刷新属性,不仅支持基本数据类型,还支持结构、切片和 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的辛勤付出。

