GoWindGoWind
Home
Framework
GoWind Toolkit
  • Open Source

    • GoWind Admin (Admin Platform)
    • GoWind CMS (Content Management)
    • GoWind UBA (Behavior Analytics)
    • GoWind Shop (E-commerce)
    • GoWind Kanban (Kanban Boards)
    • GoWind Ledger (Personal Finance)
    • GoWind ShortPlay (Short Drama)
    • GoWind Ops (Operations Platform)
    • RushWind (Rust Ecosystem)
  • Open Core (Community + Enterprise)

    • GoWind OA (Office Collaboration)
    • GoWind ERP (Procure-to-Pay)
    • GoWind WMS (Warehousing)
  • Commercial

    • GoWind IM (Instant Messaging)
    • GoWind IoT (IoT Platform)
    • GoWind Edu (AI Education)
    • GoWind MES (Manufacturing Execution)
    • GoWind CDC (Data Pipeline)
    • GoWind SDP (Zero-Trust Gateway)
    • GoWind Quant (Quant Research)
    • GoWind Trade Radar (Export Sourcing)
    • GoWind Game Radar (Game Greenlight)
  • 简体中文
  • English
GitHub
Home
Framework
GoWind Toolkit
  • Open Source

    • GoWind Admin (Admin Platform)
    • GoWind CMS (Content Management)
    • GoWind UBA (Behavior Analytics)
    • GoWind Shop (E-commerce)
    • GoWind Kanban (Kanban Boards)
    • GoWind Ledger (Personal Finance)
    • GoWind ShortPlay (Short Drama)
    • GoWind Ops (Operations Platform)
    • RushWind (Rust Ecosystem)
  • Open Core (Community + Enterprise)

    • GoWind OA (Office Collaboration)
    • GoWind ERP (Procure-to-Pay)
    • GoWind WMS (Warehousing)
  • Commercial

    • GoWind IM (Instant Messaging)
    • GoWind IoT (IoT Platform)
    • GoWind Edu (AI Education)
    • GoWind MES (Manufacturing Execution)
    • GoWind CDC (Data Pipeline)
    • GoWind SDP (Zero-Trust Gateway)
    • GoWind Quant (Quant Research)
    • GoWind Trade Radar (Export Sourcing)
    • GoWind Game Radar (Game Greenlight)
  • 简体中文
  • English
GitHub
  • Introduction

    • GoWind Framework
    • Framework Architecture
  • go-wind Core

    • go-wind Core Framework
    • App Lifecycle Management
    • Context Propagation
    • Transport Abstraction
    • Log Facade Interface
  • go-wind-plugins

    • go-wind-plugins Plugin Overview
    • Plugin Configuration System
    • Plugin Registration Mechanism (SPI)
    • Logging Adapter Plugins
    • Transport Protocol Plugins
    • Message Middleware Plugins
    • Encoding Plugins
    • Security and Authentication Plugins
    • Distributed Tracing Plugins
    • Cache Plugins
    • Object Storage Plugins (OSS)
    • Rate Limiting Plugins
    • Metrics Plugins
    • AI Plugins
    • Workflow Plugins
    • Database and Cache Plugins
    • Bootstrap Integration and Gateway Plugins
    • Compression and Serialization Plugins
    • Template Rendering and Validation Plugins
  • go-wind-bootstrap

    • go-wind-bootstrap: The Declarative Bootstrap
    • The Bootstrap Configuration System
    • The Bootstrap SPI Mechanism
    • Declarative Middleware Orchestration
    • Bootstrap Command-Line Integration
    • Bootstrap Practical Examples
  • go-wind-flow Workflow Engine

    • GoWind Flow Process Engine
  • Tutorials

    • Quick Start Tutorial
    • Custom Plugin Development Tutorial
    • Multi-Protocol Listening Tutorial
    • Framework Migration Guide

The Bootstrap SPI Mechanism

go-wind-bootstrap implements Builder self-registration and automatic assembly through the SPI (Service Provider Interface) mechanism: each adapter subpackage registers its Builder with the global registry in init(), and users only need to blank-import the adapter package for the framework to assemble components automatically according to configuration.

1. How the SPI Works

2. The Builder Registry at a Glance

The registry is organized by domain, with one string-keyed map per domain. Keys are type constants (e.g. ServerTypeHTTP = "http", LoggerTypeZap = "zap") that match the type values in configuration:

DomainBuilder SignatureRegistration Function
Serverfunc(cfg *v1.Server) (transport.Server, error)MustRegisterServerBuilder
Logfunc(cfg *v1.Logger) (log.Logger, func(), error)MustRegisterLogBuilder
Registryfunc(ctx, cfg *v1.Registry) (Registry, func(), error)MustRegisterRegistryAction
Configfunc(ctx, cfg *v1.Config) (func(), error)MustRegisterConfigAction
Tracerfunc(cfg *v1.Tracer) (interface{}, func(), error)MustRegisterTracerBuilder
Metricsfunc(cfg *v1.Metrics) (func(), error)MustRegisterMetricsBuilder
Brokerfunc(ctx, cfg *v1.Broker) (any, func(), error)MustRegisterBrokerBuilder
Storagefunc(ctx, cfg *v1.Storage) (any, func(), error)MustRegisterStorageBuilder
Aifunc(ctx, cfg *v1.Ai) (any, func(), error)MustRegisterAiBuilder
Workflowfunc(ctx, cfg *v1.Workflow) (any, func(), error)MustRegisterWorkflowBuilder
Cachefunc(ctx, cfg *v1.Cache) (any, func(), error)MustRegisterCacheBuilder
ScriptEnginefunc(ctx, cfg *v1.Script) (any, func(), error)MustRegisterScriptEngineBuilder
Databasefunc(ctx, cfg *v1.Database) (any, func(), error)MustRegisterDatabaseBuilder

Each domain also provides RegisterXxx (returns an error) and MustRegisterXxx (panics on error, intended for init()), plus a ListXxxBuilders() diagnostic function.

3. SPI Registration Examples

3.1 Adapter Self-Registration

The init() of each adapter subpackage is a single line:

// transport/http/http.go
package http

func init() {
    bootstrap.MustRegisterServerBuilder(bootstrap.ServerTypeHTTP, newBuilder)
}
// log/zap/zap.go
func init() {
    bootstrap.MustRegisterLogBuilder(bootstrap.LoggerTypeZap, newBuilder)
}
// database/gorm/client.go
func init() {
    bootstrap.MustRegisterDatabaseBuilder(bootstrap.DatabaseTypeGorm, newBuilder)
}

Blank-importing the adapter packages in main.go runs their init() automatically:

import (
    _ "github.com/tx7do/go-wind-bootstrap/log/zap"       // Registers the Zap Logger Builder
    _ "github.com/tx7do/go-wind-bootstrap/transport/http" // Registers the HTTP Server Builder
)

3.2 Automatic Assembly by the Bootstrap

When parsing configuration, the Bootstrap checks each proto optional field one by one; on a hit, it looks up the table and invokes the corresponding Builder:

server:
  http:          # ServerTypeHTTP → serverBuilders["http"]
    addr: ":8080"

logger:
  type: zap      # LoggerTypeZap → logBuilders["zap"]
  zap:
    level: info

Taking HTTP as an example, newBuilder reads cfg.GetHttp(), creates the Server, mounts middleware according to configuration, and then invokes the route registration callbacks registered via RegisterServerSetup in order.

4. SPI Assembly Order

Bootstrap parses the configuration of each domain in a fixed order:

5. Custom Builders

When the built-in adapters do not meet your needs, register custom Builders using the same APIs as the built-in adapters:

// Register a custom Registry Action (signature in builder.go: takes the Registry
// configuration and returns a Registry instance + cleanup)
bootstrap.MustRegisterRegistryAction(bootstrap.RegistryTypeConsul,
    func(ctx context.Context, cfg *v1.Registry) (bootstrap.Registry, func(), error) {
        // Create the Consul service registry client...
        return reg, func() { /* cleanup */ }, nil
    },
)

// Register a custom Broker Builder
bootstrap.MustRegisterBrokerBuilder(bootstrap.BrokerTypeKafka,
    func(ctx context.Context, cfg *v1.Broker) (any, func(), error) {
        // Create the Kafka broker...
        return broker, func() { /* cleanup */ }, nil
    },
)

6. Instance Lifecycle

Each Builder may return an optional cleanup function. The Bootstrap aggregates the cleanups of all domains into a single cleanup chain that runs uniformly after the application stops (releasing connections, deregistering instances, flushing the tracer, etc.):

  • Semi-sealed mode: triggered by bctx.Cleanup();
  • Fully sealed mode: RunApp internally runs defer cleanup() automatically.

Service registry instance registration/deregistration is wired uniformly at the bootstrap layer: after the application starts (wind.WithAfterStart), instances are registered with all configured service registries using real listening endpoints; at graceful shutdown (wind.WithBeforeStop), they are deregistered before the servers stop — the Builder is only responsible for creating the service registry client itself.

7. SPI vs. Google Wire

AspectBootstrap SPIGoogle Wire
Dependency approachRuntime registrationCompile-time generation
FlexibilityHigh (configuration-driven implementation selection)Medium (fixed at compile time)
Type safetyChecked at runtimeChecked at compile time
Configuration-drivenYAML-drivenCode-driven
Learning costLowMedium

Related Documentation

  • Bootstrap Introduction
  • The Bootstrap Configuration System
  • The Plugin Registration Mechanism
  • Custom Plugin Development Tutorial
Edit this page
Last Updated:: 11/3/26, 2:14 PM
Contributors: Bobo
Prev
The Bootstrap Configuration System
Next
Declarative Middleware Orchestration