运行时依赖
安装命令
点击复制技能文档
角色:你是用 fx 构建长驻服务的 Go 架构师。在组合根处拼装依赖图,把生命周期从 init() 挪到 hook,以模块为复用单元。
使用 uber-go/fx 进行 Go 应用拼装 基于反射的 DI 容器(uber-go/dig)+ 生命周期、模块系统、信号感知运行循环、结构化事件日志。面向启动顺序、优雅关闭、模块化拼装都重要的长驻服务。
官方资源 pkg.go.dev/go.uber.org/fx uber-go.github.io/fx github.com/uber-go/fx
本技能不 exhaustive,请查阅库文档与示例。Context7 可作为发现平台。
安装 go get go.uber.org/fx
fx vs. dig fx 基于 dig,共享反射容器引擎,DI 原语(Provide、Invoke、In/Out、命名值、值组)完全一致——fx.In/fx.Out 只是 dig.In/dig.Out 的别名。
fx 额外提供:
- 生命周期 hook:fx.Lifecycle OnStart/OnStop
- 模块系统:fx.Module 带作用域装饰器
- 信号感知运行循环:app.Run() 阻塞等待 SIGINT/SIGTERM
- 结构化事件日志:fx.WithLogger / fxevent
- 启动/关闭超时:fx.StartTimeout / fx.StopTimeout
长驻服务(HTTP、worker、daemon)选 fx;CLI、库、测试、已有生命周期管理的场景选裸 dig。
应用入口
import "go.uber.org/fx"
app := fx.New(
fx.Provide(NewLogger, NewDatabase, NewServer),
fx.Invoke(RegisterRoutes)
)
app.Run() // 阻塞至 SIGINT/SIGTERM,然后执行 OnStop
启动阶段 fx.New 仅验证类型(不运行构造函数); app.Start(ctx) 按拓扑顺序执行 fx.Invoke 并触发 OnStart; main 阻塞于 app.Done(); app.Stop(ctx) 逆序触发 OnStop。 默认超时 15 秒,可用 fx.StartTimeout / fx.StopTimeout 覆盖。
Provide 与 Invoke
fx.New(
fx.Provide(NewLogger, NewDatabase, NewServer), // 惰性
fx.Invoke(RegisterRoutes, StartMetricsExporter), // Start 阶段必执行
)
无 Invoke(直接或间接)引用时,构造函数不会运行。生命周期 Hook 注入 fx.Lifecycle 并追加 hook。构造函数应快速返回,长任务放 OnStart。
func NewHTTPServer(lc fx.Lifecycle, log zap.Logger, cfg Config) http.Server {
srv := &http.Server{Addr: cfg.Addr}
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
ln, err := net.Listen("tcp", srv.Addr)
if err != nil { return err }
go srv.Serve(ln)
return nil
},
OnStop: func(ctx context.Context) error { return srv.Shutdown(ctx) },
})
return srv
}
回调 context 受 StartTimeout/StopTimeout 限制;OnStart 须快速返回,阻塞工作放 goroutine。
fx.StartHook / fx.StopHook / fx.StartStopHook 支持简化签名:
lc.Append(fx.StartStopHook(srv.Start, srv.Stop))参数与结果对象 dig.In / dig.Out 重导出为 fx.In / fx.Out。依赖 ≥4 或需命名/分组/可选标签时使用。
type ServerParams struct { fx.In Loggerzap.Logger DB sql.DB Cache redis.Clientoptional:"true"Routes []http.Handlergroup:"routes"}
fx.Annotate 无需 fx.Out 即可加标签或绑定接口:
fx.Provide(
fx.Annotate(NewPrimaryDB, fx.ResultTags(name:"primary")),
fx.Annotate(NewPostgresDB, fx.As(new(Database))),
fx.Annotate(NewUserHandler, fx.As(new(http.Handler)), fx.ResultTags(group:"routes"))
)
值组
多构造函数 → 单切片消费者;常用于路由、健康检查、指标收集。
group:"routes,flatten" 可展开切片而非嵌套。顺序不保证,需顺序时自行提供有序切片。
fx.Module 将 provider、invoke、子模块分组,支持作用域装饰器与私有依赖,便于大型服务图管理。