{"id":20213694,"url":"https://github.com/go-spring/spring-core","last_synced_at":"2026-04-02T15:14:03.101Z","repository":{"id":45147893,"uuid":"286021423","full_name":"go-spring/spring-core","owner":"go-spring","description":"🔥 [released] Go-Spring is a high-performance Go framework inspired by Spring Boot, offering DI, auto-configuration, and lifecycle management while maintaining Go's simplicity and efficiency.","archived":false,"fork":false,"pushed_at":"2026-03-27T11:52:25.000Z","size":4877,"stargazers_count":78,"open_issues_count":5,"forks_count":16,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-03-27T22:55:21.495Z","etag":null,"topics":["auto-configuration","ioc","spring","spring-boot","starter"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/go-spring.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-08-08T10:25:38.000Z","updated_at":"2026-03-27T11:51:54.000Z","dependencies_parsed_at":"2025-01-05T02:19:54.827Z","dependency_job_id":"64a59b0d-5199-4b43-a4d9-f73ec818b8e7","html_url":"https://github.com/go-spring/spring-core","commit_stats":null,"previous_names":["go-spring/go-spring-core"],"tags_count":28,"template":false,"template_full_name":null,"purl":"pkg:github/go-spring/spring-core","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-spring%2Fspring-core","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-spring%2Fspring-core/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-spring%2Fspring-core/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-spring%2Fspring-core/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/go-spring","download_url":"https://codeload.github.com/go-spring/spring-core/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-spring%2Fspring-core/sbom","scorecard":{"id":432493,"data":{"date":"2025-08-11","repo":{"name":"github.com/go-spring/spring-core","commit":"13189a9185ebad3c287c7c8c667e2d3debce8e1e"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.4,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/3 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/lint.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/go-spring/spring-core/lint.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/go-spring/spring-core/lint.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/lint.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/go-spring/spring-core/lint.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/go-spring/spring-core/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/go-spring/spring-core/test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/go-spring/spring-core/test.yml/main?enable=pin","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T03:42:04.255Z","repository_id":45147893,"created_at":"2025-08-19T03:42:04.255Z","updated_at":"2025-08-19T03:42:04.255Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31308751,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auto-configuration","ioc","spring","spring-boot","starter"],"created_at":"2024-11-14T06:10:56.923Z","updated_at":"2026-04-02T15:14:03.089Z","avatar_url":"https://github.com/go-spring.png","language":"Go","readme":"# Go-Spring\n\n\u003cdiv\u003e\n   \u003cimg src=\"https://img.shields.io/github/license/go-spring/spring-core\" alt=\"license\"/\u003e\n   \u003cimg src=\"https://img.shields.io/github/go-mod/go-version/go-spring/spring-core\" alt=\"go-version\"/\u003e\n   \u003cimg src=\"https://img.shields.io/github/v/release/go-spring/spring-core?include_prereleases\" alt=\"release\"/\u003e\n   \u003ca href=\"https://codecov.io/gh/go-spring/spring-core\" \u003e\n      \u003cimg src=\"https://codecov.io/gh/go-spring/spring-core/branch/main/graph/badge.svg?token=SX7CV1T0O8\" alt=\"test-coverage\"/\u003e\n   \u003c/a\u003e\n   \u003ca href=\"https://goreportcard.com/report/github.com/go-spring/spring-core\"\u003e\n      \u003cimg src=\"https://goreportcard.com/badge/github.com/go-spring/spring-core\" alt=\"Go Report Card\"/\u003e\n   \u003c/a\u003e\n   \u003ca href=\"https://deepwiki.com/go-spring/spring-core\"\u003e\n      \u003cimg src=\"https://deepwiki.com/badge.svg\" alt=\"Ask DeepWiki\"\u003e\n   \u003c/a\u003e\n\u003c/div\u003e\n\n[English](README.md) | [中文](README_CN.md)\n\n\u003e The project has been officially released, welcome to use!\n\n**Go-Spring is a high-performance framework for modern Go application development,\ninspired by Spring / Spring Boot from the Java ecosystem.**\n\nIts design philosophy deeply integrates native Go language features,\ninheriting mature development paradigms from the Spring ecosystem —\nDependency Injection (DI), auto-configuration, and lifecycle management —\nwhile avoiding the complexity and performance overhead\nthat traditional frameworks may incur.\n\nGo-Spring allows developers to enjoy the convenience of high-level abstraction and\nautomated development while maintaining Go's native style and execution efficiency.\n\n**Whether you're building monolithic applications or\nconstructing distributed microservices systems,\nGo-Spring provides a unified and flexible development experience.**\n\nThe framework simplifies project initialization in an \"out-of-the-box\" way,\nreduces boilerplate code, and does not enforce an intrusive architecture,\nallowing developers to focus on implementing business logic.\n\nGo-Spring is committed to improving development efficiency,\nenhancing maintainability, and ensuring system consistency,\nmaking it a milestone framework in the Go ecosystem.\n\n## 1. 🚀 Features Overview\n\nGo-Spring combines mature design ideas of dependency injection and auto-configuration,\nadheres to Go's philosophy of \"simplicity is beauty\",\nand provides rich practical features to help developers\nefficiently build modern Go applications:\n\n1. ⚡ **Extreme startup performance, zero reflection at runtime**\n   - Pre-registers beans based on Go's native `init()` mechanism, **no runtime scanning**,\n     startup takes only milliseconds;\n   - Reflection is only used during **initialization phase** to complete dependency injection,\n     after initialization **zero reflection throughout runtime**,\n     performance comparable to handwritten code.\n\n2. 🧩 **Non-intrusive IoC container**\n   - No forced interface dependencies or inheritance structure,\n     business logic maintains native Go style, truly non-intrusive;\n   - Supports standalone dependency injection usage,\n     can also be used for full-stack framework development,\n     flexible and unbound, fully compatible with Go standard library;\n   - Provides complete bean lifecycle management,\n     natively supports `Init` and `Destroy` hooks.\n\n3. 💉 **Flexible and diverse Bean dependency injection**\n   - Supports multiple injection methods: struct field injection, constructor injection,\n     constructor parameter injection;\n   - Supports multiple matching strategies by type, name, and tags,\n     covering various scenario requirements.\n\n4. 🏷️ **Convenient Value configuration binding**\n   - Configuration values are directly bound to struct fields, no manual parsing required;\n   - Supports default value syntax `${key:=default}`, elegant fallback;\n   - Built-in field validation, automatically checks configuration correctness.\n\n5. 🎯 **Powerful conditional injection system**\n   - Supports dynamically deciding whether to register a bean\n     based on configuration, environment, context and other conditions;\n   - Provides multiple commonly used condition types,\n     supports logical combinations (AND/OR/NOT);\n   - Lays a solid foundation for modular auto-wiring.\n\n6. ⚙️ **Layered configuration system**\n   - Supports multi-source (command line, environment variables, configuration files, memory) and\n     multi-format (YAML, TOML, Properties) configuration loading;\n   - Clear configuration priority layering, automatic overriding,\n     natively supports multi-environment isolation;\n   - Supports configuration import, can integrate remote configuration centers to\n     meet cloud-native deployment requirements.\n\n7. 🔄 **Hot configuration reload, real-time effective**\n   - Original `gs.Dync[T]` generic natively supports hot reloading,\n     configuration changes don't require application restart;\n   - **Fully compatible with Value binding syntax**, consistent usage, easy to get started;\n   - Configuration automatically synchronizes to fields, enabling gray release and\n     online parameter tuning in one step.\n\n8. 🏗️ **Modular auto-wiring**\n   - Modular auto-wiring based on conditional injection;\n   - Modular design, assembled on demand, truly out-of-the-box;\n   - The ecosystem provides rich Starter modules\n     for quick integration of various functions.\n\n9. 🔌 **Clear application runtime model**\n   - Abstracts two runtime models: `Runner` (one-time tasks) and `Server` (long-running services);\n   - Built-in HTTP Server launcher, supports concurrent startup of multiple services;\n   - Complete lifecycle hooks, supports graceful startup/shutdown and signal handling.\n\n10. 🧪 **Native `go test` integration for testing**\n    - `gs.RunTest()` starts the container with one click, automatically completes dependency injection;\n    - Automatic graceful shutdown after tests, no extra scaffolding code required.\n\n11. 🪵 **Out-of-the-box logging system in the ecosystem**\n    - Go-Spring ecosystem provides natively integrated structured logging module;\n    - Unified logging interface, supports multiple outputs,\n      adaptable to various logging implementations.\n\n## 2. 📦 Installation\n\nGo-Spring uses Go Modules for dependency management, installation is straightforward:\n\n```bash\ngo get github.com/go-spring/spring-core\n```\n\n## 3. 🚀 Quick Start\n\nGo-Spring prides itself on being \"out-of-the-box\".\nBelow are two examples to quickly experience the framework's powerful capabilities:\n- **Example 1** shows how Go-Spring **perfectly integrates with the standard library**\n  without changing your coding habits\n- **Example 2** shows the core framework features such as dependency injection,\n  configuration binding, dynamic refresh, etc.\n\n### Example 1: Minimal API Service (Seamless integration with standard library)\n\nThis example demonstrates Go-Spring's **perfect compatibility**\nwith the standard library `net/http`.\nYou can use standard library writing directly,\nand the framework only handles lifecycle management:\n\n```go\npackage main\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/go-spring/spring-core/gs\"\n)\n\nfunc main() {\n\t// Define routes entirely using Go standard library http.Handler\n\t// Go-Spring won't force you to replace it with framework-specific routing syntax\n\thttp.HandleFunc(\"/echo\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Write([]byte(\"hello world!\"))\n\t})\n\n\t// Start the application with just one line, the framework automatically takes over:\n\t// - Signal handling (graceful exit on Ctrl+C)\n\t// - Lifecycle management\n\t// - Automatic waiting for all services to exit\n\tgs.Run()\n}\n```\n\nAccess the service:\n\n```bash\ncurl http://127.0.0.1:9090/echo\n# Output: hello world!\n```\n\nThis minimal example already reflects Go-Spring's design philosophy:\n\n- ✅ **Non-intrusive compatibility**: Directly use Go standard library `http`, no code rewriting needed\n- ✅ **Zero configuration startup**: No complicated configuration files, just `gs.Run()` to run\n- ✅ **Lifecycle enhancement**: The framework automatically handles signal capture and graceful exit,\n   eliminating template code handwriting\n- ✅ **Gradual integration**: You can use only lifecycle management,\n  or gradually introduce DI and configuration capabilities\n\n### Example 2: Core Features Showcase (Dependency Injection + Dynamic Configuration)\n\nThis example demonstrates how multiple core features of Go-Spring work together,\nshowcasing **dependency injection**, **configuration binding**, **dynamic configuration hot reloading**,\n**custom configuration at startup** and other capabilities:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/go-spring/spring-core/gs\"\n)\n\nconst timeLayout = \"2006-01-02 15:04:05.999 -0700 MST\"\n\n// Register Bean during init() phase, based on Go native mechanism, no runtime scanning needed\nfunc init() {\n\tgs.Provide(\u0026Service{})\n\n\t// Parameter s *Service will be automatically injected by the framework\n\tgs.Provide(func(s *Service) *gs.HttpServeMux {\n\t\thttp.HandleFunc(\"/echo\", s.Echo)\n\t\thttp.HandleFunc(\"/refresh\", s.Refresh)\n\t\treturn \u0026gs.HttpServeMux{Handler: http.DefaultServeMux}\n\t})\n}\n\ntype Service struct {\n\t// Auto-inject configuration refresher by type\n\tAppConfig   *gs.PropertiesRefresher `autowire:\"\"`\n\t// Bind configuration value to field through value tag\n\tStartTime   time.Time               `value:\"${start-time}\"`\n\t// Use gs.Dync[T] generic to support hot reloading, automatically syncs after configuration changes\n\tRefreshTime gs.Dync[time.Time]      `value:\"${refresh-time}\"`\n}\n\nfunc (s *Service) Echo(w http.ResponseWriter, r *http.Request) {\n\tstr := fmt.Sprintf(\"start-time: %s refresh-time: %s\",\n\t\ts.StartTime.Format(timeLayout),\n\t\ts.RefreshTime.Value().Format(timeLayout))\n\tw.Write([]byte(str))\n}\n\nfunc (s *Service) Refresh(w http.ResponseWriter, r *http.Request) {\n\t// Simulate environment variable change, trigger configuration refresh.\n\t// According to priority rules, environment variables have higher priority\n\t// than in-memory configuration\n\tos.Setenv(\"GS_REFRESH-TIME\", time.Now().Format(timeLayout))\n\t// Call refresh interface, all fields wrapped with Dync will be automatically updated\n\ts.AppConfig.RefreshProperties()\n\tw.Write([]byte(\"OK!\"))\n}\n\nfunc main() {\n\t// Set configuration through code during application startup phase,\n\t// this belongs to the in-memory configuration level\n\tgs.Configure(func(app gs.App) {\n\t\tapp.Property(\"start-time\", time.Now().Format(timeLayout))\n\t\tapp.Property(\"refresh-time\", time.Now().Format(timeLayout))\n\t}).Run()\n}\n```\n\nAccess the service:\n\n```bash\ncurl http://127.0.0.1:9090/echo     # Check current time (start time and refresh time)\ncurl http://127.0.0.1:9090/refresh  # Trigger hot refresh, refresh time will update\n```\n\nThis example covers many core features of Go-Spring:\n\n- ✅ **Bean registration and dependency injection**: Register beans via `gs.Provide()`,\n  framework automatically completes dependency injection\n- ✅ **Custom configuration at startup**: Supports dynamic configuration through code\n  during application startup, flexibly adapts to different scenarios\n- ✅ **Automatic configuration binding**: `value` tag directly binds configuration\n  to struct fields, no manual parsing required\n- ✅ **Layered configuration system**: Follows priority rules:\n  environment variables \u003e in-memory configuration \u003e default values,\n  naturally supports multiple environments\n- ✅ **Dynamic configuration hot reloading**: Natively supported via `gs.Dync[T]` generic,\n  configuration changes take effect in real-time without application restart\n- ✅ **Configuration refresh mechanism**: Provides `PropertiesRefresher`\n  to support manual triggering of configuration reload, can be used with configuration centers\n\n## 4. 🧩 Bean Management\n\nIn Go-Spring, **Beans are the core building blocks of your application**,\nsimilar to the concept of \"components\" in other dependency injection frameworks.\nThe entire system is organized around Bean registration, initialization,\ndependency injection, and lifecycle management.\n\nGo-Spring's design philosophy is **\"Ready at compile time, minimal at runtime\"**:\n- No reliance on runtime scanning, all beans complete registration metadata collection\n  during the `init()` phase\n- Reflection is only used during **initialization phase** to complete dependency injection,\n  after initialization **zero reflection throughout runtime**\n- Type safety is guaranteed by the Go compiler, runtime performance comparable\n  to handwritten code\n\nThis design fundamentally avoids the performance overhead and debugging complexity\ncaused by runtime reflection in traditional IoC frameworks,\nmaking it particularly suitable for building **high-performance, maintainable large-scale systems**.\n\nThe framework adopts a combination approach of **\"explicit registration + tag declaration + conditional assembly\"**:\n- **Explicit registration**: All beans must be explicitly registered, no implicit scanning,\n  dependencies are clear at a glance\n- **Tag declaration**: Concise declaration of injection rules through tags, no redundant configuration\n- **Conditional assembly**: Supports dynamic registration decisions based on environment,\n  naturally adapts to modular design\n\nSince it doesn't rely on runtime container scanning and there's no \"magic configuration\",\nthis approach improves debugging and operational controllability\nwhile maintaining a good development experience,\ntruly achieving the goal of **zero intrusion, (runtime) zero reflection**.\n\n### 1️⃣ Registration Methods\n\nGo-Spring provides two ways to register beans:\n\n- **`gs.Provide(objOrCtor, args...)`** - Register **global Beans** in `init()` functions\n- **`app.Provide(objOrCtor, args...)`** - Register Beans during the **application configuration phase**\n\nExample:\n\n```go\n// Register global Bean in init()\nfunc init() {\n\tgs.Provide(\u0026Service{})        // Register struct instance\n\tgs.Provide(NewService)        // Register using constructor\n\tgs.Provide(NewRepo, gs.ValueArg(\"db\")) // Constructor with parameters\n}\n\n// Register Bean in application configuration\ngs.Configure(func(app gs.App) {\n\tapp.Provide(\u0026MyService{})\n\tapp.Root(\u0026Bootstrap{}) // Mark as root Bean, triggers dependency injection\n})\n```\n\n\u003e **💡 On-demand instantiation and `Root`**\n\u003e Go-Spring defaults to an **on-demand instantiation** strategy —\n\u003e only beans that are depended on or marked as `Root` will be instantiated.\n\u003e Beans marked via `app.Root()` serve as entry points to the application,\n\u003e and the framework automatically completes their dependency injection and instantiation.\n\n### 2️⃣ Injection Methods\n\nGo-Spring provides multiple flexible dependency injection methods.\n\n#### 1. Struct Field Injection\n\nInject configuration items or beans into struct fields through tags,\n**suitable for most scenarios** and is the most commonly used injection method.\n\n```go\ntype App struct {\n\tLogger    *Logger      `autowire:\"\"`           // Auto-inject Bean by type\n\tFilters   []*Filter    `autowire:\"access,*?\"  // Inject multiple Beans, allowed to not exist\n\tStartTime time.Time    `value:\"${start-time}\" // Bind configuration value\n}\n```\n\nSyntax explanation:\n\n- `value:\"${key}\"` or `value:\"${key:=default}\"`: Binds configuration value to field, supports default values\n- `autowire:\"\"`: Automatic injection by **type**, matches directly when type is unique\n- `autowire:\"?\"`: Inject by type, allows non-existence, field is nil if not exists\n- `autowire:\"name?\"`: Match by type and name, allows non-existence, field is nil if not exists\n- `autowire:\"a,*?\"`: First match name a, then inject remaining beans of the same type,\n  injection order matches registration order\n- `autowire:\"a,b,c\"`: Exact match multiple beans by specified names,\n  order strictly matches declaration order\n- `autowire:\"a,*?,b\"`: Exact match multiple specified beans by name,\n  keep remaining other beans, overall ordered\n\n#### 2. Constructor Injection\n\nAutomatic injection through function parameters, Go-Spring automatically infers\nand matches dependent beans.\n\n```go\nfunc NewService(logger *Logger) *Service {\n\treturn \u0026Service{Logger: logger}\n}\n\ngs.Provide(NewService)\n```\n\n#### 3. Constructor Parameter Injection\n\nYou can **explicitly specify the injection behavior** for each parameter\nthrough parameter wrappers, more suitable for complex construction logic.\n\n```go\ngs.Provide(NewService,\n\tgs.TagArg(\"${log.level}\"), // Inject value from configuration\n\tgs.ValueArg(8080),         // Inject fixed value directly\n\tgs.BindArg(connectDB),     // Inject after processing through function\n)\n```\n\nAvailable parameter types:\n\n| Parameter Wrapper | Purpose | Usage Scenario |\n|-----------|------|---------|\n| `gs.TagArg(\"${key}\")` | Extract value from configuration and inject | Need configuration value directly as constructor parameter |\n| `gs.ValueArg(val)` | Inject fixed value | Know the parameter value definitely, no need to get from container |\n| `gs.IndexArg(i, arg)` | Specify injection by parameter position | Need to skip certain parameters, or customize injection for specific parameters |\n| `gs.BindArg(fn, args...)` | Inject after processing via function | Need conversion or custom processing for injected values |\n\nWhile this approach may seem slightly verbose, it gives you **complete control over the injection process**,\nwhich is very useful in complex scenarios.\n\n### 3️⃣ Lifecycle and Configuration Options\n\nGo-Spring provides rich APIs for configuring bean metadata, lifecycle hooks, and dependencies.\nThrough method chaining, you can fully define all behaviors of a bean.\n\n```go\ngs.Provide(NewService).\n\tName(\"myService\").                           // Specify Bean name\n\tInit(func(s *Service) { ... }).              // Initialization function\n\tDestroy(func(s *Service) { ... }).           // Destruction function\n\tCondition(gs.OnProperty(\"feature.enabled\")). // Conditional registration\n\tDependsOn(gs.BeanIDFor[*Repo]()).            // Declare explicit dependency\n\tExport(gs.As[ServiceInterface]()).           // Export as interface\n\tExport(gs.As[gs.Runner]())                   // Supports multiple interface exports\n```\n\nComplete configuration option description:\n\n| Option | Purpose | Description |\n|------|------|------|\n| `Name(string)` | Specify Bean name | Used to distinguish when multiple beans of the same type exist, used with `autowire:\"name\"` |\n| `Init(fn)` | Initialization function | Called after bean dependency injection is complete, also supports `InitMethod(\"Init\")` specification by method name |\n| `Destroy(fn)` | Destruction function | Called when application shuts down, also supports `DestroyMethod(\"Close\")` specification by method name |\n| `DependsOn(...)` | Declare dependency | Specify other beans that this bean depends on, ensuring correct initialization order |\n| `Condition(...)` | Conditional registration | Only registers the current bean when condition is met, skips registration otherwise |\n| `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 |\n\n### 4️⃣ Configuration Classes and Sub-Beans\n\nGo-Spring supports capabilities similar to Spring Boot's `@Configuration` —\nyou can mark a bean as a **configuration class**,\nand the framework will automatically scan the configuration class's methods\nand automatically register method return values as sub-beans.\nThis approach is very suitable for organizing configuration modularly.\n\n#### Usage\n\n```go\n// Define configuration class\ntype DataSourceConfig struct {}\n\n// Method return values are automatically registered as Beans\nfunc (c *DataSourceConfig) PrimaryDB() *sql.DB {\n\t// Write your database connection creation logic here\n\treturn \u0026sql.DB{ /* ... */ }\n}\n\n// Multiple methods can define multiple related Beans\nfunc (c *DataSourceConfig) ReplicaDB() *sql.DB {\n\treturn \u0026sql.DB{ /* ... */ }\n}\n\nfunc init() {\n\t// Mark as configuration class via .Configuration(),\n\t// framework automatically scans and registers all sub-beans\n\tgs.Provide(\u0026DataSourceConfig{}).Configuration()\n}\n```\n\n#### Inclusion/Exclusion Rules\n\nYou can precisely control which methods need to be scanned and registered using regular expressions:\n\n```go\nfunc init() {\n\t// Only include methods matching New.* pattern\n\tgs.Provide(\u0026Config{}).Configuration(gs.Configuration{\n\t\tIncludes: []string{\"New.*\"}, // Include patterns\n\t\tExcludes: []string{\"Test.*\"}, // Exclude patterns\n\t})\n}\n```\n\n- If you don't specify `Includes`, it defaults to scanning all public methods\n- Regex syntax follows Go standard `regexp` package specification,\n  please avoid incomplete regular expressions like `*`\n- Scanned methods must **return Bean instances**, supports two signatures: `(T)` or `(T, error)`\n\n## 5. ⚙️ Configuration Management\n\nGo-Spring provides a **layered-designed, flexible and powerful** configuration management system\nthat supports loading configuration from multiple sources, natively meeting enterprise requirements\nsuch as multi-environment isolation and dynamic updates.\nWhether for local development, containerized deployment, or cloud-native architecture,\nGo-Spring provides a consistent and concise configuration experience.\n\nThe framework automatically merges configuration items from different sources at startup\nand automatically overrides according to **priority rules**,\nso you don't need to manually handle configuration merging logic.\n\nGo-Spring supports three mainstream configuration formats out of the box:\n**YAML** (`.yaml`/`.yml`, recommended), **Properties** (`.properties`), and **TOML** (`.toml`).\nThe framework automatically recognizes the format based on the file extension.\n\n### 1️⃣ 🔖 Configuration Binding\n\nThe most convenient way to configure in Go-Spring\nis to bind configuration directly to struct fields via the `value` tag,\nno manual parsing required:\n\n```go\ntype ServerConfig struct {\n\tPort    int    `value:\"${server.port:=8080}\"`      // With default value\n\tHost    string `value:\"${server.host:=localhost}\"` // With default value\n\tEnabled bool   `value:\"${server.enabled:=true}\"`   // Boolean type\n}\n```\n\n**Syntax explanation:**\n- `${key}`: Binds the value of configuration key `key` to the field\n- `${key:=default}`: Uses `default` as the default value if the configuration key doesn't exist\n- Supports almost all Go primitive types: `int`/`int64`/`uint`/`float64`/`bool`/`string`, etc.,\n  also supports custom types like `time.Duration`\n\n### 2️⃣ 📌 Configuration Priority\n\nGo-Spring adopts a clear **priority layering** design,\nwhere higher priority configurations automatically override\nlower priority configurations with the same name.\nPriorities are listed from highest to lowest below:\n\n| Priority | Configuration Source | Description | Usage Scenario |\n|:------:|----------------|------|---------|\n| 1 ⬆️ | **Command Line Arguments** | `-Dkey=value` | Temporary override configuration, quick debugging verification |\n| 2 | **Environment Variables** | System environment variables | Containerized deployment, twelve-factor apps |\n| 3 | **profile configuration** | `app-{profile}.ext` | Multi-environment isolation (dev/test/prod) |\n| 4 | **app base configuration** | `app.ext` | Default base configuration |\n| 5 | **In-memory configuration** | Programmatic setting via `app.Property()` | Unit testing, dynamic override |\n| 6 ⬇️ | **Tag default values** | `${key:=default}` | Final fallback, default values |\n\n\u003e **💡 Core Priority Rule**\n\u003e **Later-loaded configurations have higher priority**, configurations closer to runtime take precedence,\n\u003e which matches intuition.\n\n\u003e **💡 Configuration Import Rule**\n\u003e Both base configuration and profile configuration support importing external configurations via `spring.app.imports`,\n\u003e **Later imported configurations have higher priority than the file's original configuration**,\n\u003e overriding in import order.\n\n### 3️⃣ 📝 Detailed Description of Each Configuration Source\n\n#### 1. Command Line Arguments\nInjected using `-Dkey=value` format, highest priority,\nsuitable for quickly overriding runtime configuration:\n```bash\ngo run main.go -Dserver.port=9090 -Dapp.env=production\n```\n\n#### 2. Environment Variables\nDirectly read from OS environment variables, best practice for containerized deployment:\n```bash\nexport SERVER_PORT=9090\nexport APP_ENV=production\nexport SPRING_PROFILES_ACTIVE=dev\n```\n\n\u003e 💡 Go-Spring automatically converts underscores in environment variables to dots,\n\u003e for example `SERVER_PORT` maps to `server.port`.\n\n#### 3. profile configuration (multi-environment isolation)\nAchieves environment isolation by activating different profiles,\nfile naming format is `app-{profile}.{ext}`:\n```bash\n# Activate dev environment\nexport SPRING_PROFILES_ACTIVE=dev\n```\nThe framework automatically loads `app-dev.yaml` (or other formats),\nwhich has higher priority than base configuration.\nConfigurations imported in profile configuration also follow the later-import-first rule.\n\n#### 4. Base Configuration File\nBy default loads `conf/app` with extension (e.g., `conf/app.yaml`),\nsuitable for storing general base configuration:\n```\n./conf/app.yaml\n./conf/app.properties\n```\nBase configuration supports importing external configurations via `spring.app.imports`.\n\n#### Configuration Import (import)\nBoth base configuration and profile configuration support importing external configurations\nvia `spring.app.imports`, making it easy to split and reuse:\n\n```yaml\n# app.yaml\nspring:\n  app:\n    imports:\n      - \"database.yaml\"       # Split database configuration\n      - \"redis.yaml\"          # Split Redis configuration\n      - \"nacos://server.json\" # Import from remote configuration center (requires extension)\n```\n\nImporting executes in the order declared, **later imported configurations override keys\nwith the same name from earlier imports and original configuration**.\nThis mechanism is very suitable for configuration splitting\nand integrating remote configuration centers (Nacos, etcd, etc.).\n\n#### 5. Application In-Memory Configuration\nProgrammatic configuration setting via code during application startup,\ncommonly used for testing or dynamic scenarios:\n```go\ngs.Configure(func(app gs.App) {\n    app.Property(\"app.name\", \"test-app\")\n    app.Property(\"feature.enabled\", true)\n})\n```\n\n#### 6. Struct Tag Default Values\nEmbedded default values through tags, serve as the final fallback for the configuration system:\n```go\ntype Config struct {\n\tPort int    `value:\"${server.port:=8080}\"`\n\tEnv  string `value:\"${app.env:=development}\"`\n}\n```\n\n## 6. 🔍 Conditional Injection\n\nDrawing inspiration from Spring's `@Conditional` concept,\nGo-Spring implements a flexible and powerful conditional injection system.\nIt dynamically decides whether to register beans based on configuration,\nenvironment, context and other conditions, achieving \"assembly on demand\".\nThis is particularly crucial in scenarios such as multi-environment deployment,\nplugin architecture, feature toggles, and gray release.\n\n### 1️⃣ 🎯 Common Condition Types\n\n- **`gs.OnProperty(\"key\")`**: Activates when the specified configuration key exists\n- **`gs.OnBean[Type](\"name\")`**: Activates when a bean of the specified type/name exists\n- **`gs.OnMissingBean[Type](\"name\")`**: Activates when a bean of the specified type/name does **not** exist\n- **`gs.OnSingleBean[Type](\"name\")`**: Activates when the specified type/name bean is the only instance\n- **`gs.OnFunc(func(ctx gs.ConditionContext) (bool, error))`**: Uses custom conditional logic to determine activation\n\nExample:\n\n```go\ngs.Provide(NewService).\n\tCondition(gs.OnProperty(\"service.enabled\"))\n```\n\n`NewService` will only be registered if `service.enabled=true` exists in the configuration file.\n\n### 2️⃣ 🔁 Supports Combined Conditions\n\nGo-Spring supports combining multiple conditions to build more complex judgment logic:\n\n- **`gs.Not(...)`** - Negates a condition\n- **`gs.And(...)`** - All conditions must be satisfied\n- **`gs.Or(...)`** - Any condition being satisfied is sufficient\n- **`gs.None(...)`** - All conditions must not be satisfied\n\nExample:\n\n```go\ngs.Provide(NewService).\n  Condition(\n      gs.And(\n          gs.OnProperty(\"feature.enabled\"),\n          gs.Not(gs.OnBean[*DeprecatedService]()),\n      ),\n  )\n```\n\nThis bean will be enabled when `feature.enabled` is turned on\nand `*DeprecatedService` is not registered.\n\n## 7. 📦 Module and Starter Mechanism\n\nDrawing inspiration from Spring Boot's Starter concept,\nGo-Spring provides a **Module** mechanism to implement auto-configuration and modular assembly.\nThrough Module, you can organize related beans together to create \"out-of-the-box\" functional modules.\n\n### 1️⃣ 🎯 What is a Module?\n\nA Module is **Go-Spring's conditional configuration module** mechanism\nthat can dynamically decide whether to register a set of related beans\nbased on configuration properties.\nThis is ideal for:\n\n- 🧩 **Developing starters for various functions** (such as Redis, MySQL, gRPC, etc.)\n- 🏗️ **Organizing code by functional modules**, achieving loosely coupled architecture\n- ⚡ **Automatically enabling/disabling features based on configuration**, truly assembled on demand\n\nThe core interface is very concise:\n\n```go\ngs.Module(condition gs.PropertyCondition, fn func(r gs.BeanProvider, p flatten.Storage) error)\n```\n\n- `condition`: Property condition, only when the condition is met\n  will the beans inside the module be registered (usually created with `gs.OnProperty(\"key\")`)\n- `fn`: Module initialization function, register all beans of this module\n  in batch within the function\n- `r`: Bean registrar, usage is exactly the same as global `gs.Provide()`\n- `p`: Configuration storage, you can read configuration from it for dynamic binding\n\n### 2️⃣ 💡 Typical Scenario: Custom Starter\n\nSuppose you want to develop a Redis Starter, you can organize your code like this:\n\n```go\npackage redis\n\nimport (\n\t\"github.com/go-spring/spring-core/gs\"\n\t\"github.com/go-spring/stdlib/flatten\"\n)\n\n// Cache interface\ntype Cache interface {\n\tGet(key string) (string, error)\n\tSet(key string, value string) error\n}\n\nfunc init() {\n\t// Automatically enable the Redis module when redis.host configuration is detected\n\t// If the condition is not met, beans inside the module won't be registered,\n\t// doesn't affect application startup\n\tgs.Module(gs.OnProperty(\"redis.host\"),\n\t\tfunc(r gs.BeanProvider, p flatten.Storage) error {\n\t\t\t// 1. Register Redis Client, specify name, initialization and destruction methods\n\t\t\tr.Provide(NewRedisClient).\n\t\t\t\tName(\"redisClient\").\n\t\t\t\tInitMethod(\"Connect\").   // Call Connect after dependency injection completes\n\t\t\t\tDestroyMethod(\"Close\"). // Call Close when application shuts down to release resources\n\n\t\t\t// 2. Register Redis-based Cache implementation and export as Cache interface\n\t\t\t// This allows other components to inject by interface, decoupled from specific implementation\n\t\t\tr.Provide(NewRedisCache).\n\t\t\t\tExport(gs.As[Cache]())\n\n\t\t\t// You can continue to register other related beans...\n\t\t\treturn nil\n\t\t})\n}\n```\n\nIt's very simple for users to use, just add to the configuration file:\n\n```yaml\nredis:\n  host: localhost\n  port: 6379\n  password: xxx\n  db: 0\n```\n\nGo-Spring will automatically detect the configuration,\nand when the condition is met, automatically execute the module\nto register all related beans. Users **don't need to write any manual registration code**,\ntruly out-of-the-box!\n\n### 3️⃣ ✨ Special Usage: Group Batch Registration\n\nGo-Spring also provides `gs.Group` convenient syntax for handling a common scenario:\n**batch creating multiple beans from a map in configuration**.\nEach map entry is automatically converted to a named bean,\nwith the map key as the bean name. Usage example:\n\n```go\n// Batch create multiple HTTP clients from configuration\ngs.Group(\n\t\"${http.clients}\",           // Path to map-type configuration in configuration\n\tfunc(cfg HTTPClientConfig) (*HTTPClient, error) {\n\t\treturn NewHTTPClient(cfg) // Create a client instance for each configuration entry\n\t},\n\tfunc(c *HTTPClient) error {\n\t\treturn c.Close()          // Optional: destruction function for resource cleanup\n\t},\n)\n```\n\nCorresponding YAML configuration:\n\n```yaml\nhttp:\n  clients:\n    serviceA:  # map key \"serviceA\" becomes the bean name\n      baseURL: \"http://a.example.com\"\n      timeout: 30s\n    serviceB:  # map key \"serviceB\" becomes the bean name\n      baseURL: \"http://b.example.com\"\n      timeout: 60s\n```\n\nThis approach is very suitable for scenarios that require batch creation of beans based on configuration,\nsuch as **multiple data sources**, **multi-tenancy**, **dynamic plugins**, etc.\n\n## 8. 🔁 Dynamic Configuration\n\nGo-Spring natively supports a **lightweight configuration hot update** mechanism.\nThrough the generic type `gs.Dync[T]` and `RefreshProperties()`,\napplications can perceive configuration changes in real-time at runtime\nwithout restarting the application.\nThis feature is very useful in scenarios such as **gray release**,\n**dynamic parameter tuning**, and **configuration center integration**\nin microservices architecture.\n\n### 1️⃣ 🌡 Usage\n\nDivided into two steps: **declare dynamic field** and **trigger refresh**.\n\n#### 1. Declare dynamic fields using `gs.Dync[T]`\n\nWrap fields with the generic type `gs.Dync[T]`,\nand the framework will automatically listen for configuration changes\nand update in real-time:\n\n```go\ntype Config struct {\n\tVersion gs.Dync[string] `value:\"${app.version}\"` // Declare as dynamic configuration\n}\n```\n\nTo use, get the latest current value through the `.Value()` method:\n\n```go\nversion := config.Version.Value() // Always gets the latest value\n```\n\nThe framework will **automatically update** the internal value when the configuration changes,\nno manual handling required from you.\n\n#### 2. Call `RefreshProperties()` to trigger refresh\n\nAfter external configuration changes, you need to inject `*gs.PropertiesRefresher`\nand call its method to trigger the refresh:\n\n```go\nfunc RefreshHandler(w http.ResponseWriter, r *http.Request, refresher *gs.PropertiesRefresher) {\n\t// Simulate configuration change (in real scenarios it's usually pushed by configuration center)\n\tos.Setenv(\"APP_VERSION\", \"v2.0.1\")\n\t// Trigger refresh, all gs.Dync[T] fields will update automatically\n\t_ = refresher.RefreshProperties()\n\tfmt.Fprintln(w, \"Version updated!\")\n}\n```\n\n## 9. ⏳ Application Lifecycle and Service Model\n\nGo-Spring abstracts components in the application runtime phase\ninto two core roles: `Runner` and `Server`, with clear division of responsibilities:\n\n| Role | Execution Method | Typical Scenarios |\n|:----:|:--------:|---------|\n| **Runner** | One-time execution | Database initialization, cache warming, data migration and other startup tasks |\n| **Server** | Long-running | HTTP services, gRPC services, WebSocket services, etc. |\n\nAll roles are registered via `.Export(gs.As[Interface]())`.\n\n\u003e **Design Note**: Early versions included a `Job` type for background scheduled tasks,\n\u003e but to simplify the model and reduce cognitive burden, it has been removed in the latest version.\n\u003e For background tasks that need to run continuously, it's recommended to implement directly\n\u003e using the `Server` interface and handle with a loop in the `Run` method.\n\n### 1️⃣ Example: Runner\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"github.com/go-spring/spring-core/gs\"\n)\n\nfunc init() {\n\t// Register Bootstrap and export as Runner interface\n\tgs.Provide(\u0026Bootstrap{}).Export(gs.As[gs.Runner]())\n}\n\ntype Bootstrap struct{}\n\nfunc (b *Bootstrap) Run(ctx context.Context) error {\n\tfmt.Println(\"Bootstrap: Initialization completed...\")\n\treturn nil // If returns error, application startup will be terminated\n}\n\nfunc main() {\n\tgs.Run()\n}\n```\n\n### 2️⃣ 📌 Custom Server\n\nGo-Spring provides a generic `Server` interface that allows you\nto conveniently integrate various service components.\nAll registered `Server`s automatically integrate into the application lifecycle,\nand the framework handles general logic such as **concurrent startup**,\n**graceful shutdown**, and **signal handling**.\n\n**Server interface definition:**\n\n```go\ntype Server interface {\n\tRun(ctx context.Context, sig ReadySignal) error\n\tStop() error\n}\n```\n\n- `Run(ctx context.Context, sig ReadySignal)`: Start the service,\n  wait for the startup signal before officially providing services externally\n- `Stop() error`: Gracefully shuts down the service, releases resources\n\n**ReadySignal interface:**\n\n```go\ntype ReadySignal interface {\n\tTriggerAndWait() \u003c-chan struct{}\n}\n```\n\nThe role of `ReadySignal` is to **wait for all Servers to complete listening binding\nbefore uniformly providing services externally**, avoiding errors caused\nby accepting requests before startup completes.\n\n### 3️⃣ Example: HTTP Server Integration\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/http\"\n\t\"github.com/go-spring/spring-core/gs\"\n)\n\nfunc init() {\n\tgs.Provide(NewServer).Export(gs.As[gs.Server]())\n}\n\ntype MyServer struct {\n\tsvr *http.Server\n}\n\n// NewServer creates HTTP service instance\nfunc NewServer() *MyServer {\n\treturn \u0026MyServer{\n\t\tsvr: \u0026http.Server{Addr: \":8080\"},\n\t}\n}\n\nfunc (s *MyServer) Run(ctx context.Context, sig gs.ReadySignal) error {\n\t// Complete port listening binding first\n\tln, err := net.Listen(\"tcp\", s.svr.Addr)\n\tif err != nil {\n\t\treturn err // Binding fails, return directly, terminate startup\n\t}\n\t// Wait for all servers to complete startup, then start accepting connections\n\t\u003c-sig.TriggerAndWait()\n\t// Officially start serving\n\treturn s.svr.Serve(ln)\n}\n\nfunc (s *MyServer) Stop() error {\n\t// Gracefully shutdown HTTP service\n\treturn s.svr.Shutdown(context.Background())\n}\n```\n\n### 4️⃣ Example: gRPC Server Integration\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"github.com/go-spring/spring-core/gs\"\n\t\"google.golang.org/grpc\"\n)\n\ntype GRPCServer struct {\n\tsvr *grpc.Server\n}\n\nfunc (s *GRPCServer) Run(ctx context.Context, sig gs.ReadySignal) error {\n\tlis, err := net.Listen(\"tcp\", \":9595\")\n\tif err != nil {\n\t\treturn err\n\t}\n\t\u003c-sig.TriggerAndWait() // Wait for all services to complete startup\n\treturn s.svr.Serve(lis)\n}\n\nfunc (s *GRPCServer) Stop() error {\n\ts.svr.GracefulStop() // Graceful stop\n\treturn nil\n}\n```\n\n### 5️⃣ 💡 Multiple Servers Running Concurrently\n\nAll services registered via `.Export(gs.As[gs.Server]())` will be **started concurrently**\nwhen `gs.Run()` is called, and exit signals will be handled uniformly:\n\n```go\nfunc init() {\n\t// HTTP and gRPC services run concurrently\n\tgs.Provide(\u0026HTTPServer{}).Export(gs.As[gs.Server]())\n\tgs.Provide(\u0026GRPCServer{}).Export(gs.As[gs.Server]())\n}\n```\n\nAfter receiving an exit signal (such as Ctrl+C), the framework uniformly calls\nthe `Stop()` method of all servers to achieve graceful shutdown.\n\n## 10. 🧪 Unit Testing\n\nThanks to Go-Spring's **non-intrusive design**, you can completely write unit tests\nin native Go way, and there's no mandatory requirement to use special testing capabilities\nfrom the framework.\n\nFor simple unit tests, just manually instantiate the test object\nand pass in dependencies manually:\n\n```go\nfunc TestMyService(t *testing.T) {\n\t// Manually create dependencies (can use Mock)\n\tmockRepo := NewMockRepo()\n\t// Manually instantiate the service under test\n\tservice := NewMyService(mockRepo)\n\n\t// Test directly, no need to start container\n\tresult := service.DoSomething()\n\tassert.Equal(t, \"ok\", result)\n}\n```\n\n### 1️⃣ When to use `gs.RunTest()`\n\nWhen you need to write **integration tests** that require starting the complete container\nand automatically completing dependency injection, Go-Spring provides `gs.RunTest()`\nwith native `go test` integration, which is very convenient:\n\n```go\npackage main\n\nimport (\n\t\"testing\"\n\t\"github.com/go-spring/spring-core/gs\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestExample(t *testing.T) {\n\t// gs.RunTest automatically creates container, completes dependency injection,\n\t// automatically closes after test\n\tgs.RunTest(t, func(ts *struct {\n\t\tDB    *MyDB    `autowire:\"\"`\n\t\tCache *Cache  `autowire:\"\"`\n\t}) {\n\t\t// All dependencies are already automatically injected, ready to use directly\n\t\tresult := ts.DB.Query(\"SELECT ...\")\n\t\tassert.NotNil(t, result)\n\t})\n}\n```\n\n### 2️⃣ ✨ Core Features\n\n- ✅ **Fully native compatible**: Seamlessly integrated with standard `go test`, no special test runner required\n- ✅ **Automatic dependency injection**: Declare required beans in the test parameter struct, framework injects automatically\n- ✅ **Automatic resource cleanup**: Automatically calls destruction methods after tests, graceful shutdown\n\n## 11. 📚 Comparison with Other Frameworks\n\nBelow is a feature comparison between Go-Spring and other mainstream Go dependency injection frameworks:\n\n| Feature Point | Go-Spring | Wire | fx | dig |\n|:-------|:---------:|:----:|:--:|:---:|\n| Runtime IoC Container | ✓ | ✗ | ✓ | ✓ |\n| No runtime scanning (pre-registration based on init()) | ✓ | ✓ | ✗ | ✗ |\n| Zero reflection runtime (no reflection after initialization) | ✓ | ✓ | ✗ | ✗ |\n| Compile-time type checking | Partial | ✓ | ✗ | ✗ |\n| Conditional Beans support | ✓ | ✗ | ✗ | ✗ |\n| Modular auto-wiring (Starter mechanism) | ✓ | ✗ | ✗ | ✗ |\n| Dynamic configuration hot reloading | ✓ | ✗ | ✗ | ✗ |\n| Lifecycle management | ✓ | ✗ | ✓ | ✗ |\n| Configuration property auto-binding | ✓ | ✗ | ✗ | ✗ |\n| Non-intrusive design (no modification to original struct) | ✓ | ✓ | ✗ | ✓ |\n\n## 12. 🤝 Relationship with Other Go Ecosystems\n\nGo-Spring **does not intend to replace any existing Go framework**,\nbut acts as a \"glue\" to help you integrate the entire Go ecosystem.\n\n### 1️⃣ Design Philosophy\n\nGo-Spring deeply respects Go's native ecosystem,\nthe framework is fully compatible with the standard library and various third-party frameworks:\n\n- ✅ **Can be used with any web framework like Gin/Echo/Chi**,\n  the framework doesn't force you to replace your routing syntax\n- ✅ **Can be used with gRPC/protobuf ecosystem**, auto-wire services\n- ✅ **Can be used with sql/database or ORM frameworks**, configuration-driven multiple data sources\n- ✅ **Fully compatible with Go standard library `net/http`, `context`, etc.**, no intrusive modifications\n\n### 2️⃣ Positioning and Division of Labor\n\n| Component | What Go-Spring does | You can choose |\n|:---:|----------|---------|\n| **Dependency Injection** | ✅ Full responsibility | - |\n| **Configuration Management** | ✅ Full responsibility (multi-source, hot reloading) | - |\n| **Web Routing** | Optional integration | Gin, Echo, Chi, standard library `net/http` |\n| **ORM/Database** | Optional integration | GORM, XORM, sqlx, standard library `database/sql` |\n| **Logging** | Provides unified interface | Zap, Logrus, slog, etc. |\n| **Service Discovery/Registration** | Integratable via Starter | etcd, Consul, Nacos |\n\nIn one sentence: **Go-Spring helps you manage dependencies and configuration well,\nleaving the rest to the tools you're familiar with**.\n\n## 13. 📖 Further Learning\n\nWant to get started quickly? Check out these resources:\n\n- 📖 **Complete Documentation**: [go-spring/go-spring](https://github.com/go-spring/go-spring)\n- 💡 **Example Projects**: [go-spring/examples](https://github.com/go-spring/go-spring/tree/master/docs/4.examples)\n- 📦 **Ecosystem Starters**: The [Go-Spring organization](https://github.com/go-spring)\n  maintains many out-of-the-box modules\n\n## 14. 🏢 Who's Using Go-Spring?\n\nMany companies are using Go-Spring to build microservices applications in production:\n\n- ...\n\n\u003e If your company or project is also using Go-Spring,\n\u003e feel free to submit a PR to showcase your project here!\n\n## 15. 💬 Feedback and Communication\n\n- 🐛 **Bug Reports**: [GitHub Issues](https://github.com/go-spring/spring-core/issues)\n- 💡 **Feature Suggestions**: Welcome to submit an Issue to join the discussion\n- ⭐ **Star Support**: If you like this project, feel free to give a star to encourage us!\n\n## 16. 🤝 Contributing\n\nGo-Spring is an open source community-driven project, we welcome **all forms of contributions**:\n\n- Fix documentation errors\n- Fix bugs\n- Submit feature suggestions\n- Contribute new features\n- Share your usage experience\n\nPlease check [CONTRIBUTING.md](CONTRIBUTING.md) for how to participate.\n\n### 💬 QQ Group\n\nWelcome to join the QQ group for discussion:\n\n\u003cimg src=\"https://raw.githubusercontent.com/go-spring/go-spring-website/master/qq(1).jpeg\" width=\"140\" alt=\"qq-group\"/\u003e\n\n### 📱 WeChat Official Account\n\nFollow the WeChat official account for the latest updates:\n\n\u003cimg src=\"https://raw.githubusercontent.com/go-spring/go-spring-website/master/go-spring-action.jpg\" width=\"140\" alt=\"wechat-public\"/\u003e\n\n### 🎉 Acknowledgments\n\nThanks to JetBrains for the [IntelliJ IDEA](https://www.jetbrains.com/idea/) open source license,\nwhich greatly facilitates project development.\n\n### 🛡️ License\n\nApache License 2.0, see [LICENSE](LICENSE) for details.\n","funding_links":[],"categories":["Miscellaneous","杂项","Web Frameworks","Microsoft Office"],"sub_categories":["Dependency Injection","依赖注入","Utility/Miscellaneous"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-spring%2Fspring-core","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgo-spring%2Fspring-core","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-spring%2Fspring-core/lists"}