Skip to content

FAQ - Frequently Asked Questions

This page collects global frequently asked questions about Go-Spring. If you are looking for questions about a specific module, see the corresponding module documentation:


Project Overview

Q: What is Go-Spring? What is its design philosophy?

A: Go-Spring is a Go dependency injection framework that inherits ideas from Spring. Its core design philosophy is:

  • Keep Go's native style: do not forcibly imitate Java Spring; solve Go problems in the Go way
  • Discover and solve problems early: all dependency resolution is completed at startup, and the container is not involved at runtime
  • Explicit over implicit: all dependencies are clearly visible, with no magic, avoiding hard-to-debug surprises
  • Conditional mutual exclusion over override: Beans with the same name cannot be implicitly overridden; conditional matching decides which one takes effect
  • Simplicity is beauty: avoid overengineering and solve only real problems

Q: How is Go-Spring different from other Go dependency injection frameworks (Wire, dig, fx)?

A:

FeatureGo-SpringWiredigfx
Dependency resolution timingStartup-time reflectionCompile-time code generationRuntime reflectionRuntime reflection
Singleton by default-
Conditional registration-
Configuration bindingBuilt inNot built inNot built inNot built in
Circular dependency supportAutomatically handled by field injectionNot supported
Batch registration Group-

Go-Spring chooses the startup-time reflection path, which brings several benefits:

  • No extra code generation step is needed, making the development workflow simpler
  • Supports conditional registration and dynamically deciding which Beans take effect based on configuration
  • Automatically handles circular dependencies through field injection
  • Built-in configuration binding without requiring third-party libraries

If you prefer compile-time code generation, Wire is a great choice. If you like Go-Spring's design philosophy, it will feel very natural to use.

Q: Why is it called Go-Spring, and what is its relationship with Java Spring?

A: Go-Spring inherits Spring's core ideas of Inversion of Control and Dependency Injection, but it is not a Go reimplementation of Java Spring.

We insist on Go's native design philosophy and do not copy Java Spring concepts directly into Go. Many design decisions differ from Java Spring, such as:

  • Go-Spring does not support dynamically retrieving Beans at runtime; it resolves everything once at startup
  • Go-Spring does not allow Bean overriding; it insists on conditional mutual exclusion
  • Go-Spring requires interfaces to be explicitly exported and does not infer them automatically

So it inherits the ideas, but it is not a port. It is a redesign in the Go way.

Q: Is Go-Spring stable now? Can it be used in production?

A: Go-Spring has gone through years of iteration. Its core features are stable and have already been used in production environments.


Getting Started

Q: How do I create a Go-Spring project from scratch?

A: We recommend starting from the starter template:

bash
# Clone the template
git clone https://github.com/go-spring/starter.git my-project
cd my-project
# Fetch dependencies
go mod tidy
# Run
go run main.go

The template is already configured with the most commonly used starters, so you can develop directly on top of it.

A: Go-Spring does not enforce a project structure. We recommend following Go community conventions:

my-project/
├── main.go           # Entry file
├── go.mod            # Dependency management
├── config/           # Configuration types
├── service/          # Business services
├── controller/       # HTTP controllers
├── repository/       # Data access layer
└── model/            # Data models

Basic principle: layer by domain and keep dependencies clear.

Q: Where can I find complete example projects?

A: Example projects are collected in go-spring/examples, which you can use as references.


Development

Q: How do I run tests?

A: Exactly the same as native Go:

bash
go test ./...

For detailed testing usage, see 07-testing.md.

Q: How can I contribute?

A: Contributions are welcome!

  • Report issues: github.com/go-spring/go-spring/issues
  • Submit Pull Requests: fork the repository, make changes, and submit a PR
  • Before contributing, read the repository root CODING_STYLE.md to understand the coding conventions

Q: Why was my Bean not registered?

A: Common reasons:

  1. You forgot to call gs.Provide in init() to register it
  2. Its conditions were not satisfied and it was pruned by conditional matching; check your condition configuration
  3. The Bean is not depended on. Go-Spring creates Beans on demand, so Beans that are not depended on are not instantiated (though they are still registered)

Q: Why does startup fail with "conflict: bean already registered"?

A: This error means two Beans of the same type and same name were registered at the same time.

Solutions:

  1. If you really need two instances, give them different names with .Name("xxx")
  2. If only one should take effect under different conditions, add conditional matching such as OnProfiles
  3. If you want to override in tests, ctx.Provide in tests does not affect the global context, so it is safe to override there

Go-Spring does not allow Beans of the same type and same name to coexist under the same condition. This is a design choice to avoid hard-to-debug problems caused by implicit overriding.


Performance

Q: Is Go-Spring slow to start? Does it have high runtime overhead?

A:

  • Startup overhead: all dependency injection is completed at startup. Startup time is positively correlated with the number of Beans, and typical projects start within tens of milliseconds
  • Runtime overhead: after startup, all metadata is cleaned up. There is no extra runtime overhead, and performance is the same as handwritten code
  • Memory usage: only your Beans consume memory. The container itself uses almost no memory after startup

So there is no need to worry about performance. Go-Spring is very lightweight at runtime.

Q: How can I optimize startup speed?

A:

  1. On-demand creation is enabled by default, so Beans that are not depended on are not created, saving time
  2. Register only the Beans you actually need; avoid registering large amounts of unused code
  3. Split modules and use conditional registration, enabling them only when needed

About This Documentation

This documentation is continuously improving. If you have new questions, feel free to submit an Issue to add them.