fx是一个golang的依赖注入框架,主要的内容有几个注入方法,以及钩子函数
下面是最简单的demo使用。
package main
import (
"context"
"fx_demo/modu"
"log"
"net/http"
"go.uber.org/fx"
)
// Invoke 注册的函数的运行是有顺序的,而 Provide 注入的构造函数并没有顺序
func main() {
app := fx.New(
modu.Module,
fx.Provide( //构造函数,依赖的内容可以自动注入,依赖的内容在方法入参中,会从容器注入
NewHTTPServer,
NewGreetingService,
),
fx.Supply(stu), // 函数传入的参数是已经构造完毕的值(value),也就是说 Provide(NewC) → Supply(C) , 其中 C = NewC(…)
// 当其他构造函数依赖于类型C时,不通过调用 NewC 生成,而是直接使用提供的 C。
fx.Populate(), //中传入的targets必须得是目标类型TypeX的指针类型 *TypeX,哪怕 TypeX 本身就是指针类型
// populate方法传入一个指针,指针的值从容器中注入
fx.Invoke(RegisterHTTPServer), //注册一些在app启动时需要执行的函数,被注册的 func 的入参,通过 Provide 注入的构造函数生成
)
app.Run()
}
type Student string
var stu Student = "leon"
// HTTP服务器
type HTTPServer struct {
server *http.Server
}
func NewHTTPServer() *HTTPServer {
return &HTTPServer{
server: &http.Server{
Addr: ":8080",
},
}
}
// 问候服务
type GreetingService interface {
Greet() string
}
type greetingService struct{}
func NewGreetingService() GreetingService {
return &greetingService{}
}
func (s *greetingService) Greet() string {
return "Hello, FX!"
}
// 注册HTTP处理函数
func RegisterHTTPServer(lc fx.Lifecycle, server *HTTPServer, greeting GreetingService) {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(greeting.Greet()))
})
server.server.Handler = mux
// 添加钩子函数
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
log.Println("Starting HTTP server on :8080")
go server.server.ListenAndServe()
return nil
},
OnStop: func(ctx context.Context) error {
log.Println("Stopping HTTP server")
return server.server.Shutdown(ctx)
},
})
}
模块化管理
package modu
import (
"go.uber.org/fx"
"go.uber.org/zap"
)
// 使用这个方法!
var Module = fx.Options(
fx.Provide(ProvideLogger),
)
func ProvideLogger() *zap.Logger {
return zap.NewExample()
}
参考:
https://karlvenk.github.io/2022/10/02/fx-md/