Go-Spring
CategoryMiscellaneous
SubcategoryDependency Injection
Stars84
A high-performance Go framework inspired by Spring Boot, offering DI, auto-configuration, and lifecycle management while maintaining Go's simplicity and efficiency
About Go-Spring
This large README is shown as a plain-text preview. Read the full README at the source
# Go-Spring
<div>
<img src="https://img.shields.io/github/license/go-spring/spring-core" alt="license"/>
<img src="https://img.shields.io/github/go-mod/go-version/go-spring/spring-core" alt="go-version"/>
<img src="https://img.shields.io/github/v/release/go-spring/spring-core?include_prereleases" alt="release"/>
<a href="https://codecov.io/gh/go-spring/spring-core" >
<img src="https://codecov.io/gh/go-spring/spring-core/branch/main/graph/badge.svg?token=SX7CV1T0O8" alt="test-coverage"/>
</a>
<a href="https://goreportcard.com/report/github.com/go-spring/spring-core">
<img src="https://goreportcard.com/badge/github.com/go-spring/spring-core" alt="Go Report Card"/>
</a>
<a href="https://deepwiki.com/go-spring/spring-core">
<img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki">
</a>
</div>
[English](README.md) | [δΈζ](README_CN.md)
> The project has been officially released, welcome to use!
**Go-Spring is a high-performance framework for modern Go application development,
inspired by Spring / Spring Boot from the Java ecosystem.**
Its design philosophy deeply integrates native Go language features,
inheriting mature development paradigms from the Spring ecosystem β
Dependency Injection (DI), auto-configuration, and lifecycle management β
while avoiding the complexity and performance overhead
that traditional frameworks may incur.
Go-Spring allows developers to enjoy the convenience of high-level abstraction and
automated development while maintaining Go's native style and execution efficiency.
**Whether you're building monolithic applications or
constructing distributed microservices systems,
Go-Spring provides a unified and flexible development experience.**
The framework simplifies project initialization in an "out-of-the-box" way,
reduces boilerplate code, and does not enforce an intrusive architecture,
allowing developers to focus on implementing business logic.
Go-Spring is committed to improving development efficiency,
enhancing maintainability, and ensuring system consistency,
making it a milestone framework in the Go ecosystem.
## 1. π Features Overview
Go-Spring combines mature design ideas of dependency injection and auto-configuration,
adheres to Go's philosophy of "simplicity is beauty",
and provides rich practical features to help developers
efficiently build modern Go applications:
1. β‘ **Extreme startup performance, zero reflection at runtime**
- Pre-registers beans based on Go's native `init()` mechanism, **no runtime scanning**,
startup takes only milliseconds;
- Reflection is only used during **initialization phase** to complete dependency injection,
after initialization **zero reflection throughout runtime**,
performance comparable to handwritten code.
2. π§© **Non-intrusive IoC container**
- No forced interface dependencies or inheritance structure,
business logic maintains native Go style, truly non-intrusive;
- Supports standalone dependency injection usage,
can also be used for full-stack framework development,
flexible and unbound, fully compatible with Go standard library;
- Provides complete bean lifecycle management,
natively supports `Init` and `Destroy` hooks.
3. π **Flexible and diverse Bean dependency injection**
- Supports multiple injection methods: struct field injection, constructor injection,
constructor parameter injection;
- Supports multiple matching strategies by type, name, and tags,
covering various scenario requirements.
4. π·οΈ **Convenient Value configuration binding**
- Configuration values are directly bound to struct fields, no manual parsing required;
- Supports default value syntax `${key:=default}`, elegant fallback;
- Built-in field validation, automatically checks configuration correctness.
5. π― **Powerful conditional injection system**
- Supports dynamically deciding whether to register a bean
based on configuration, environment, context and other conditions;
- Provides multiple commonly used condition types,
supports logical combinations (AND/OR/NOT);
- Lays a solid foundation for modular auto-wiring.
6. βοΈ **Layered configuration system**
- Supports multi-source (command line, environment variables, configuration files, memory) and
multi-format (YAML, TOML, Properties) configuration loading;
- Clear configuration priority layering, automatic overriding,
natively supports multi-environment isolation;
- Supports configuration import, can integrate remote configuration centers to
meet cloud-native deployment requirements.
7. π **Hot configuration reload, real-time effective**
- Original `gs.Dync[T]` generic natively supports hot reloading,
configuration changes don't require application restart;
- **Fully compatible with Value binding syntax**, consistent usage, easy to get started;
- Configuration automatically synchronizes to fields, enabling gray release and
online parameter tuning in one step.
8. ποΈ **Modular auto-wiring**
- Modular auto-wiring based on conditional injection;
- Modular design, assembled on demand, truly out-of-the-box;
- The ecosystem provides rich Starter modules
for quick integration of various functions.
9. π **Clear application runtime model**
- Abstracts two runtime models: `Runner` (one-time tasks) and `Server` (long-running services);
- Built-in HTTP Server launcher, supports concurrent startup of multiple services;
- Complete lifecycle hooks, supports graceful startup/shutdown and signal handling.
10. π§ͺ **Native `go test` integration for testing**
- `gs.RunTest()` starts the container with one click, automatically completes dependency injection;
- Automatic graceful shutdown after tests, no extra scaffolding code required.
11. πͺ΅ **Out-of-the-box logging system in the ecosystem**
- Go-Spring ecosystem provides natively integrated structured logging module;
- Unified logging interface, supports multiple outputs,
adaptable to various logging implementations.
## 2. π¦ Installation
Go-Spring uses Go Modules for dependency management, installation is straightforward:
```bash
go get github.com/go-spring/spring-core
```
## 3. π Quick Start
Go-Spring prides itself on being "out-of-the-box".
Below are two examples to quickly experience the framework's powerful capabilities:
- **Example 1** shows how Go-Spring **perfectly integrates with the standard library**
without changing your coding habits
- **Example 2** shows the core framework features such as dependency injection,
configuration binding, dynamic refresh, etc.
### Example 1: Minimal API Service (Seamless integration with standard library)
This example demonstrates Go-Spring's **perfect compatibility**
with the standard library `net/http`.
You can use standard library writing directly,
and the framework only handles lifecycle management:
```go
package main
import (
"net/http"
"github.com/go-spring/spring-core/gs"
)
func main() {
// Define routes entirely using Go standard library http.Handler
// Go-Spring won't force you to replace it with framework-specific routing syntax
http.HandleFunc("/echo", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello world!"))
})
// Start the application with just one line, the framework automatically takes over:
// - Signal handling (graceful exit on Ctrl+C)
// - Lifecycle management
// - Automatic waiting for all services to exit
gs.Run()
}
```
Access the service:
```bash
curl http://127.0.0.1:9090/echo
# Output: hello world!
```
This minimal example already reflects Go-Spring's design philosophy:
- β
**Non-intrusive compatibility**: Directly use Go standard library `http`, no code rewriting needed
- β
**Zero configuration startup**: No complicated configuration files, just `gs.Run()` to run
- β
**Lifecycle enhancement**: The framework automatically handles signal capture and graceful exit,
eliminating template code handwriting
- β
**Gradual integration**: You can use only lifecycle management,
or gradually introduce DI and configuration capabilities
### Example 2: Core Features Showcase (Dependency Injection + Dynamic Configuration)
This example demonstrates how multiple core features of Go-Spring work together,
showcasing **dependency injection**, **configuration binding**, **dynamic configuration hot reloading**,
**custom configuration at startup** and other capabilities:
```go
package main
import (
"fmt"
"net/http"
"os"
"time"
"github.com/go-spring/spring-core/gs"
)
const timeLayout = "2006-01-02 15:04:05.999 -0700 MST"
// Register Bean during init() phase, based on Go native mechanism, no runtime scanning needed
func init() {
gs.Provide(&Service{})
// Parameter s *Service will be automatically injected by the framework
gs.Provide(func(s *Service) *gs.HttpServeMux {
http.HandleFunc("/echo", s.Echo)
http.HandleFunc("/refresh", s.Refresh)
return &gs.HttpServeMux{Handler: http.DefaultServeMux}
})
}
type Service struct {
// Auto-inject configuration refresher by type
AppConfig *gs.PropertiesRefresher `autowire:""`
// Bind configuration value to field through value tag
StartTime time.Time `value:"${start-time}"`
// Use gs.Dync[T] generic to support hot reloading, automatically syncs after configuration changes
RefreshTime gs.Dync[time.Time] `value:"${refresh-time}"`
}
func (s *Service) Echo(w http.ResponseWriter, r *http.Request) {
str := fmt.Sprintf("start-time: %s refresh-time: %s",
s.StartTime.Format(timeLayout),
s.RefreshTime.Value().Format(timeLayout))
w.Write([]byte(str))
}
func (s *Service) Refresh(w http.ResponseWriter, r *http.Request) {
// Simulate environment variable change, trigger configuration refresh.
// According to priority rules, environment variables have higher priority
// than in-memory configuration
os.Setenv("GS_REFRESH-TIME", time.Now().Format(timeLayout))
// Call refresh interface, all fields wrapped with Dync will be automatically updated
s.AppConfig.RefreshProperties()
w.Write([]byte("OK!"))
}
func main() {
// Set configuration through code during application startup phase,
// this belongs to the in-memory configuration level
gs.Configure(func(app gs.App) {
app.Property("start-time", time.Now().Format(timeLayout))
app.Property("refresh-time", time.Now().Format(timeLayout))
}).Run()
}
```
Access the service:
```bash
curl http://127.0.0.1:9090/echo # Check current time (start time and refresh time)
curl http://127.0.0.1:9090/refresh # Trigger hot refresh, refresh time will update
```
This example covers many core features of Go-Spring:
- β
**Bean registration and dependency injection**: Register beans via `gs.Provide()`,
framework automatically completes dependency injection
- β
**Custom configuration at startup**: Supports dynamic configuration through code
during application startup, flexibly adapts to different scenarios
- β
**Automatic configuration binding**: `value` tag directly binds configuration
to struct fields, no manual parsing required
- β
**Layered configuration system**: Follows priority rules:
environment variables > in-memory configuration > default values,
naturally supports multiple environments
- β
**Dynamic configuration hot reloading**: Natively supported via `gs.Dync[T]` generic,
configuration changes take effect in real-time without application restart
- β
**Configuration refresh mechanism**: Provides `PropertiesRefresher`
to support manual triggering of configuration reload, can be used with configuration centers
## 4. π§© Bean Management
In Go-Spring, **Beans are the core building blocks of your application**,
similar to the concept of "components" in other dependency injection frameworks.
The entire system is organized around Bean registration, initialization,
dependency injection, and lifecycle management.
Go-Spring's design philosophy is **"Ready at compile time, minimal at runtime"**:
- No reliance on runtime scanning, all beans complete registration metadata collection
during the `init()` phase
- Reflection is only used during **initialization phase** to complete dependency injection,
after initialization **zero reflection throughout runtime**
- Type safety is guaranteed by the Go compiler, runtime performance comparable
to handwritten code
This design fundamentally avoids the performance overhead and debugging complexity
caused by runtime reflection in traditional IoC frameworks,
making it particularly suitable for building **high-performance, maintainable large-scale systems**.
The framework adopts a combination approach of **"explicit registration + tag declaration + conditional assembly"**:
- **Explicit registration**: All beans must be explicitly registered, no implicit scanning,
dependencies are clear at a glance
- **Tag declaration**: Concise declaration of injection rules through tags, no redundant configuration
- **Conditional assembly**: Supports dynamic registration decisions based on environment,
naturally adapts to modular design
Since it doesn't rely on runtime container scanning and there's no "magic configuration",
this approach improves debugging and operational controllability
while maintaining a good development experience,
truly achieving the goal of **zero intrusion, (runtime) zero reflection**.
### 1οΈβ£ Registration Methods
Go-Spring provides two ways to register beans:
- **`gs.Provide(objOrCtor, args...)`** - Register **global Beans** in `init()` functions
- **`app.Provide(objOrCtor, args...)`** - Register Beans during the **application configuration phase**
Example:
```go
// Register global Bean in init()
func init() {
gs.Provide(&Service{}) // Register struct instance
gs.Provide(NewService) // Register using constructor
gs.Provide(NewRepo, gs.ValueArg("db")) // Constructor with parameters
}
// Register Bean in application configuration
gs.Configure(func(app gs.App) {
app.Provide(&MyService{})
app.Root(&Bootstrap{}) // Mark as root Bean, triggers dependency injection
})
```
> **π‘ On-demand instantiation and `Root`**
> Go-Spring defaults to an **on-demand instantiation** strategy β
> only beans that are depended on or marked as `Root` will be instantiated.
> Beans marked via `app.Root()` serve as entry points to the application,
> and the framework automatically completes their dependency injection and instantiation.
### 2οΈβ£ Injection Methods
Go-Spring provides multiple flexible dependency injection methods.
#### 1. Struct Field Injection
Inject configuration items or beans into struct fields through tags,
**suitable for most scenarios** and is the most commonly used injection method.
```go
type App struct {
Logger *Logger `autowire:""` // Auto-inject Bean by type
Filters []*Filter `autowire:"access,*?" // Inject multiple Beans, allowed to not exist
StartTime time.Time `value:"${start-time}" // Bind configuration value
}
```
Syntax explanation:
- `value:"${key}"` or `value:"${key:=default}"`: Binds configuration value to field, supports default values
- `autowire:""`: Automatic injection by **type**, matches directly when type is unique
- `autowire:"?"`: Inject by type, allows non-existence, field is nil if not exists
- `autowire:"name?"`: Match by type and name, allows non-existence, field is nil if not exists
- `autowire:"a,*?"`: First match name a, then inject remaining beans of the same type,
injection order matches registration order
- `autowire:"a,b,c"`: Exact match multiple beans by specified names,
order strictly matches declaration order
- `autowire:"a,*?,b"`: Exact match multiple specified beans by name,
keep remaining other beans, overall ordered
#### 2. Constructor Injection
Automatic injection through function parameters, Go-Spring automatically infers
and matches dependent beans.
```go
func NewService(logger *Logger) *Service {
return &Service{Logger: logger}
}
gs.Provide(NewService)
```
#### 3. Constructor Parameter Injection
You can **explicitly specify the injection behavior** for each parameter
through parameter wrappers, more suitable for complex construction logic.
```go
gs.Provide(NewService,
gs.TagArg("${log.level}"), // Inject value from configuration
gs.ValueArg(8080), // Inject fixed value directly
gs.BindArg(connectDB), // Inject after processing through function
)
```
Available parameter types:
| Parameter Wrapper | Purpose | Usage Scenario |
|-----------|------|---------|
| `gs.TagArg("${key}")` | Extract value from configuration and inject | Need configuration value directly as constructor parameter |
| `gs.ValueArg(val)` | Inject fixed value | Know the parameter value definitely, no need to get from container |
| `gs.IndexArg(i, arg)` | Specify injection by parameter position | Need to skip certain parameters, or customize injection for specific parameters |
| `gs.BindArg(fn, args...)` | Inject after processing via function | Need conversion or custom processing for injected values |
While this approach may seem slightly verbose, it gives you **complete control over the injection process**,
which is very useful in complex scenarios.
### 3οΈβ£ Lifecycle and Configuration Options
Go-Spring provides rich APIs for configuring bean metadata, lifecycle hooks, and dependencies.
Through method chaining, you can fully define all behaviors of a bean.
```go
gs.Provide(NewService).
Name("myService"). // Specify Bean name
Init(func(s *Service) { ... }). // Initialization function
Destroy(func(s *Service) { ... }). // Destruction function
Condition(gs.OnProperty("feature.enabled")). // Conditional registration
DependsOn(gs.BeanIDFor[*Repo]()). // Declare explicit dependency
Export(gs.As[ServiceInterface]()). // Export as interface
Export(gs.As[gs.Runner]()) // Supports multiple interface exports
```
Complete configuration option description:
| Option | Purpose | Description |
|------|------|------|
| `Name(string)` | Specify Bean name | Used to distinguish when multiple beans of the same type exist, used with `autowire:"name"` |
| `Init(fn)` | Initialization function | Called after bean dependency injection is complete, also supports `InitMethod("Init")` specification by method name |
| `Destroy(fn)` | Destruction function | Called when application shuts down, also supports `DestroyMethod("Close")` specification by method name |
| `DependsOn(...)` | Declare dependency | Specify other beans that this bean depends on, ensuring correct initialization order |
| `Condition(...)` | Conditional registration | Only registers the current bean when condition is met, skips registration otherwise |
| `Export(as)` | Interface export | Register the bean as a specific interface to the container, convenient for injection by interface, supports multiple calls to export multiple interfaces |
### 4οΈβ£ Configuration Classes and Sub-Beans
Go-Spring supports capabilities similar to Spring Boot's `@Configuration` β
you can mark a bean as a **configuration class**,
and the framework will automatically scan the configuration class's methods
and automatically register method return values as sub-beans.
This approach is very suitable for organizing configuration modularly.
#### Usage
```go
// Define configuration class
type DataSourceConfig struct {}
// Method return values are automatically registered as Beans
func (c *DataSourceConfig) PrimaryDB() *sql.DB {
// Write your database connection creation logic here
return &sql.DB{ /* ... */ }
}
// Multiple methods can define multiple related Beans
func (c *DataSourceConfig) ReplicaDB() *sql.DB {
return &sql.DB{ /* ... */ }
}
func init() {
// Mark as configuration class via .Configuration(),
// framework automatically scans and registers all sub-beans
gs.Provide(&DataSourceConfig{}).Configuration()
}
```
Frequently Asked Questions
What is Go-Spring?
Go-Spring is a Miscellaneous library for the Go programming language. A high-performance Go framework inspired by Spring Boot, offering DI, auto-configuration, and lifecycle management while maintaining Go's simplicity and efficiency
How do I install Go-Spring?
Install Go-Spring with the Go module system using `go get go-spring/spring-core`. Check the repository for the current installation instructions.
What category does Go-Spring belong to?
Go-Spring is listed under Miscellaneous, specifically Dependency Injection.