Related samples:
Dubbo Go uses Go package initialization plus a centralized extension registry to provide most pluggable capabilities. Filters, routers, protocols, registries, load balancers, cluster strategies, tracing exporters, and metadata reporters are all loaded in this way.
The current implementation lives under common/extension. It no longer relies on ad hoc package-level maps for each type. Instead, each extension category uses the shared generic registry helper:
var loadbalances = NewRegistry[func() loadbalance.LoadBalance]("loadbalance")
func SetLoadbalance(name string, fcn func() loadbalance.LoadBalance) {
loadbalances.Register(name, fcn)
}
func GetLoadbalance(name string) loadbalance.LoadBalance {
return loadbalances.MustGet(name)()
}
The same pattern is used for:
common/extension/filter.gocommon/extension/protocol.gocommon/extension/registry.gocommon/extension/router_factory.goThis gives Dubbo Go a uniform registration model and also supports helper APIs such as unregistering and listing registered names in some categories.
init() Is UsedBuilt-in implementations usually register themselves in init():
func init() {
extension.SetLoadbalance(constant.LoadBalanceKeyRandom, NewRandomLoadBalance)
}
The same pattern appears across the runtime:
protocol/triple/triple.go registers Tripleprotocol/dubbo/dubbo_protocol.go registers Dubboprotocol/rest/rest_protocol.go registers RESTregistry/nacos/registry.go, registry/zookeeper/registry.go, registry/etcdv3/registry.go register registriesfilter/generic/filter.go, filter/metrics/filter.go, filter/graceful_shutdown/... register filterscluster/router/condition/factory.go, cluster/router/tag/factory.go, cluster/router/script/factory.go register router factoriesOnce those packages are imported, the framework can look up implementations by name.
imports PackageFor most applications, the easiest way to load built-in implementations is:
import _ "dubbo.apache.org/dubbo-go/v3/imports"
imports/imports.go is the one-stop entry that imports common built-in:
If you want a smaller runtime surface, you can also import only the concrete implementation packages you need.
A custom extension usually follows the same steps:
init() with common/extension;For example:
extension.SetFilter(...)extension.SetRouterFactory(...)extension.SetProtocol(...)extension.SetRegistry(...)The framework then resolves the implementation from configuration or runtime options by name.
Dubbo Go uses AOP-style chaining in several core abstractions:
filter.Filtercluster.Routercluster/loadbalance.LoadBalanceprotocol/base.InvokerEach implementation focuses on one concern, then participates in a larger invocation chain. This is why features such as metrics, tracing, token verification, generic invocation, and graceful shutdown can be added without changing every protocol or business handler.