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

Plugin Registration Mechanism (SPI)

go-wind-plugins uses Go's init() + blank import mechanism to implement SPI (Service Provider Interface) auto-registration, with no manual wiring required.

1. How SPI Works

2. Registry Design

// bootstrap/registry/registry.go
package registry

// Transport registry
var transportFactories = map[string]TransportFactory{}

type TransportFactory func(opts ...transport.Option) transport.Server

func RegisterTransport(name string, factory TransportFactory) {
    transportFactories[name] = factory
}

func NewTransport(name string, opts ...transport.Option) (transport.Server, error) {
    factory, ok := transportFactories[name]
    if !ok {
        return nil, fmt.Errorf("unknown transport: %s", name)
    }
    return factory(opts...), nil
}

Similarly there are RegisterDatabase, RegisterCache, RegisterBroker, RegisterLog, RegisterConfig, RegisterRegistry, and so on.

3. Plugin Registration Examples

3.1 HTTP Transport

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

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

func init() {
    registry.RegisterTransport("http", func(opts ...transport.Option) transport.Server {
        return NewServer(opts...)
    })
}

3.2 Redis Cache

// plugins/cache/redis/register.go
package redis

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

func init() {
    registry.RegisterCache("redis", func(opts ...Option) cache.Cache {
        return NewClient(opts...)
    })
}

3.3 Data-Access Client (GORM)

// plugins/crud/gorm/register.go
package gorm

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

func init() {
    registry.RegisterDatabase("gorm", func(opts ...Option) (*Repository[any, any], error) {
        return NewRepository(opts...)
    })
}

4. Blank Import

In main.go, blank imports (underscore imports) trigger init():

package main

import (
    // Transport
    _ "github.com/tx7do/go-wind-plugins/transport/http"
    _ "github.com/tx7do/go-wind-plugins/transport/grpc"

    // Log
    _ "github.com/tx7do/go-wind-plugins/log/zap"

    // Database
    _ "github.com/tx7do/go-wind-plugins/crud/gorm"

    // Cache
    _ "github.com/tx7do/go-wind-plugins/cache/redis"

    // Broker
    _ "github.com/tx7do/go-wind-plugins/broker/kafka"

    // Bootstrap
    "github.com/tx7do/go-wind-bootstrap"
)

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

If you don't import it, it won't be registered, and it won't add to the binary size.

5. On-Demand Loading

Go does not have Java-style lazy class loading, but blank imports bring these benefits:

FeatureDescription
Determined at compile timeYou know at build time which plugins are depended on
No reflectionNo reliance on reflection, high performance
Binary trimmingPlugins that are not imported are not compiled into the binary
Explicit declarationA glance at the imports tells you which plugins are in use

6. Registering Custom Plugins

Develop your own plugin and register it into the Registry:

package mycache

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

type Cache struct { ... }

func NewCache(opts ...Option) cache.Cache {
    c := &Cache{}
    for _, opt := range opts { opt(c) }
    return c
}

// Registration
func init() {
    registry.RegisterCache("mycache", func(opts ...Option) cache.Cache {
        return NewCache(opts...)
    })
}

In main.go:

import _ "myproject/plugins/mycache"

7. Registry Functions at a Glance

Registry FunctionRegistersConfig Prefix
RegisterTransportTransport Serverserver.*
RegisterLogLoggerlog.*
RegisterDatabaseData-access clientdatabase.*
RegisterCacheCachecache.*
RegisterBrokerBrokerbroker.*
RegisterConfigConfig Sourceconfig.*
RegisterRegistryService Registryregistry.*
RegisterTracerTracertracer.*
RegisterOSSObject Storageoss.*
RegisterMetricsMetricsmetrics.*
RegisterAuthAuthenticatorauth.*

8. Service Registration & Discovery Plugins (Registry)

Note the distinction between two concepts: the "registration mechanism" discussed above refers to the SPI auto-wiring of plugins; this section covers the service registration & discovery plugin family (registry/), which implements the registry.Registry (Registrar / Discovery / Watcher) interfaces, with 8 plugins in total:

PluginImport PathEngine
Consulplugins/registry/consulHashiCorp Consul
Etcdplugins/registry/etcdCoreOS etcd
Eurekaplugins/registry/eurekaNetflix Eureka
Kubernetesplugins/registry/kubernetesK8s Endpoints
Nacosplugins/registry/nacosAlibaba Cloud Nacos
Polarisplugins/registry/polarisTencent Cloud Polaris
ServiceCombplugins/registry/servicecombApache ServiceComb
Zookeeperplugins/registry/zookeeperApache ZooKeeper

Where selector / resolver belong: selector (client-side load balancing strategies RoundRobin/Random/First plus a Watch-based real-time Balancer) and resolver (a gRPC resolver.Builder, supporting addressing through the service registry via grpc.NewClient("wind:///svc", grpc.WithResolvers(...))) are two standalone modules at the repository root. They are not part of the registry family, but work alongside service registration & discovery: Discovery provides the instance list, selector picks one, and resolver plugs it into gRPC addressing.

Recent Updates

  • etcd (registry/etcd): heartbeats are now driven by a registry-level long-lived context; after a lease expires, re-registration is never abandoned (retry burst interval with a 30s cooldown), so registrations are no longer permanently lost due to transient failures.
  • eureka (registry/eureka): added a MaxRetry client option to configure the number of request retries against the Eureka Server.

Related Documents

  • Plugin Configuration System
  • Plugin Overview
  • Bootstrap SPI Mechanism
  • Custom Plugin Development Tutorial
Edit this page
Last Updated:: 11/3/26, 2:14 PM
Contributors: Bobo
Prev
Plugin Configuration System
Next
Logging Adapter Plugins