GoWind 开源生态GoWind 开源生态
首页
框架
GoWind Admin
GoWind CMS
GoWind IM
GoWind UBA
GoWind IoT
GoWind Toolkit
GoWind Quant
GitHub
首页
框架
GoWind Admin
GoWind CMS
GoWind IM
GoWind UBA
GoWind IoT
GoWind Toolkit
GoWind Quant
GitHub
  • 介绍

    • GoWind 框架
    • 框架整体架构
  • go-wind 核心

    • go-wind 核心框架
    • App 生命周期管理
    • Context 传播
    • Transport 抽象
    • Log 门面接口
  • go-wind-plugins 插件

    • go-wind-plugins 插件总览
    • 插件配置系统
    • 插件注册机制(SPI)
    • 日志适配插件
    • 传输协议插件
    • 消息中间件插件
    • 编码解码插件
    • 安全与认证插件
    • 链路追踪插件
    • 缓存插件
    • 对象存储插件(OSS)
    • 限流插件
    • 指标监控插件
    • AI 插件
    • 工作流插件
    • 数据库与缓存插件
    • Bootstrap 集成与网关插件
    • 压缩与序列化插件
    • 模板渲染与验证插件
  • go-wind-bootstrap 启动器

    • go-wind-bootstrap 声明式启动器
    • Bootstrap 配置系统
    • Bootstrap SPI 机制
    • 声明式中间件编排
    • Bootstrap CLI 工具
    • Bootstrap 实战示例
  • 教程

    • 快速入门教程
    • 自定义插件开发教程
    • 多协议同时监听教程
    • 框架迁移指南

Bootstrap SPI 机制

go-wind-bootstrap 通过 SPI(Service Provider Interface)机制实现插件自动注册和实例化。

一、SPI 工作流程

二、Registry 全貌

// bootstrap/registry/registry.go

// ===== Transport =====
func RegisterTransport(name string, factory TransportFactory)
func NewTransport(name string, opts ...) (transport.Server, error)

// ===== Log =====
func RegisterLog(name string, factory LogFactory)
func NewLog(name string, opts ...) (log.Logger, error)

// ===== Database =====
func RegisterDatabase(name string, factory DatabaseFactory)
func NewDatabase(name string, opts ...) (*ent.Client, error)

// ===== Cache =====
func RegisterCache(name string, factory CacheFactory)
func NewCache(name string, opts ...) (cache.Cache, error)

// ===== Broker =====
func RegisterBroker(name string, factory BrokerFactory)
func NewBroker(name string, opts ...) (broker.Broker, error)

// ===== Tracer =====
func RegisterTracer(name string, factory TracerFactory)
func NewTracer(name string, opts ...) (tracer.Tracer, error)

// ===== Config Source =====
func RegisterConfig(name string, factory ConfigFactory)
func NewConfig(name string, opts ...) (config.Source, error)

// ===== Registry =====
func RegisterRegistry(name string, factory RegistryFactory)
func NewRegistry(name string, opts ...) (registry.Registry, error)

// ===== OSS =====
func RegisterOSS(name string, factory OSSFactory)
func NewOSS(name string, opts ...) (oss.OSS, error)

三、SPI 注册示例

3.1 Transport 注册

// plugins/transport/http/register.go
package http

import (
    "github.com/tx7do/go-wind/transport"
    "github.com/tx7do/go-wind-bootstrap/registry"
)

func init() {
    registry.RegisterTransport("http", NewServer)
}

当 main.go 中 _ "github.com/tx7do/go-wind-plugins/transport/http" 时,init() 自动执行,将 HTTP Server 的工厂函数注册到 Registry。

3.2 Bootstrap 自动实例化

# config.yaml
server:
  http:                    # key = "http" → 查找注册名 "http"
    addr: ":8080"

Bootstrap 解析配置时:

  1. 遍历 server 下的所有 key
  2. 对每个 key,调用 registry.NewTransport(key, options...)
  3. 返回的 Server 自动添加到 App

3.3 Database 注册

// plugins/database/mysql/register.go
package mysql

func init() {
    registry.RegisterDatabase("mysql", NewClient)
}
database:
  default:                # 连接名(不参与查找)
    driver: mysql         # 查找注册名
    dsn: "..."

四、SPI 装配详解

以一个完整服务为例:

import (
    _ "github.com/tx7do/go-wind-plugins/transport/http"
    _ "github.com/tx7do/go-wind-plugins/transport/grpc"
    _ "github.com/tx7do/go-wind-plugins/log/zap"
    _ "github.com/tx7do/go-wind-plugins/database/mysql"
    _ "github.com/tx7do/go-wind-plugins/cache/redis"
    _ "github.com/tx7do/go-wind-plugins/broker/kafka"
    _ "github.com/tx7do/go-wind-plugins/registry/consul"
    _ "github.com/tx7do/go-wind-plugins/tracer/jaeger"
    _ "github.com/tx7do/go-wind-plugins/metrics/prometheus"
)

Bootstrap 装配顺序:

五、自定义 SPI

5.1 定义接口

// myapp/notifier/notifier.go
package notifier

type Notifier interface {
    Notify(ctx context.Context, message string) error
}

5.2 实现 Factory

// myapp/notifier/email/email.go
package email

type Notifier struct {
    smtpAddr string
}

func New(opts ...Option) notifier.Notifier {
    n := &Notifier{}
    for _, opt := range opts { opt(n) }
    return n
}

func (n *Notifier) Notify(ctx context.Context, msg string) error {
    // 发送邮件
    return nil
}

5.3 注册到 Bootstrap Registry

// myapp/notifier/email/register.go
package email

import "myapp/bootstrap/registry"

type Factory func(opts ...Option) notifier.Notifier

func init() {
    registry.RegisterNotifier("email", New)
}

5.4 使用

# config.yaml
notifier:
  email:
    smtp_addr: "smtp.example.com:587"
    from: "noreply@example.com"
import _ "myapp/notifier/email"

func main() {
    app := bootstrap.New("config.yaml")
    app.Run()
}

六、SPI 生命周期

每个 SPI 实例可以可选实现以下接口:

// 初始化(创建后调用)
type Initializer interface {
    Init(ctx context.Context) error
}

// 启动(App.Run 时调用)
type Starter interface {
    Start(ctx context.Context) error
}

// 停止(App 停止时逆序调用)
type Stopper interface {
    Stop(ctx context.Context) error
}

Bootstrap 自动检测并调用对应方法。

七、SPI vs Google Wire

对比项Bootstrap SPIGoogle Wire
依赖方式运行时注册编译时生成
灵活性高(可热插拔)中(编译确定)
类型安全运行时检查编译时检查
配置驱动YAML 驱动代码驱动
学习成本低中

相关文档

  • Bootstrap 介绍
  • Bootstrap 配置系统
  • 插件注册机制
  • 自定义插件开发教程
Edit this page
Last Updated:: 6/21/26, 9:28 PM
Contributors: Bobo
Prev
Bootstrap 配置系统
Next
声明式中间件编排