好,既然你想用 Java Spring Boot 的套路来对齐 Go 的分层架构,那我就用对照 + 映射 + 示例代码的方式,把这套东西讲清楚。
你只要记住一句话:

Spring Boot 的分层,几乎可以 1:1 映射到 Go,只是“依赖注入”和“接口”这块 Go 更轻量。


一、整体架构对照(核心)

层级 Spring Boot Go(Gin 为例) 职责
入口 Controller Handler 接收请求、参数校验、返回响应
业务 Service + @Transactional Service 业务逻辑、事务、编排
数据 Repository / Mapper Repository CRUD、SQL
模型 Entity / DTO Model / Struct 数据结构
配置 @Configuration wire / 手动注入 依赖组装
路由 @RequestMapping router.go URL → Handler

✅ 结论:Go 完全可以写出“Spring Boot 味”的项目结构。


二、目录结构对照(强烈建议照着建)

✅ Spring Boot

  1. controller/
  2. service/
  3. repository/
  4. entity/
  5. config/
  6. resources/templates/

✅ Go(Gin)

  1. handler/
  2. service/
  3. repository/
  4. model/
  5. router/
  6. config/
  7. templates/

几乎一模一样 👍
这就是 Go 的“企业级写法”。


三、逐层对照 + 示例代码


1️⃣ Controller / Handler(入口层)

✅ Spring Boot

  1. @RestController
  2. @RequestMapping("/articles")
  3. public class ArticleController {
  4. @Autowired
  5. private ArticleService articleService;
  6. @GetMapping("/{id}")
  7. public Article getArticle(@PathVariable String id) {
  8. return articleService.getById(id);
  9. }
  10. }

✅ Go(Gin)

  1. func RegisterRoutes(r *gin.Engine, svc *ArticleService) {
  2. h := &ArticleHandler{svc: svc}
  3. r.GET("/articles/:id", h.GetByID)
  4. }
  5. type ArticleHandler struct {
  6. svc *ArticleService
  7. }
  8. func (h *ArticleHandler) GetByID(c *gin.Context) {
  9. id := c.Param("id")
  10. article, err := h.svc.GetByID(id)
  11. if err != nil {
  12. c.JSON(500, gin.H{"error": err.Error()})
  13. return
  14. }
  15. c.JSON(200, article)
  16. }

✅ 一一对应:

  • @RequestMapping → router.go
  • @Autowired → 构造函数注入
  • @GetMapping → r.GET(...)

2️⃣ Service(业务层)

✅ Spring Boot

  1. @Service
  2. public class ArticleService {
  3. @Autowired
  4. private ArticleRepository repository;
  5. @Transactional
  6. public Article getById(String id) {
  7. return repository.findById(id);
  8. }
  9. }

✅ Go

  1. type ArticleService struct {
  2. repo *ArticleRepository
  3. }
  4. func NewArticleService(repo *ArticleRepository) *ArticleService {
  5. return &ArticleService{repo: repo}
  6. }
  7. func (s *ArticleService) GetByID(id string) (*Article, error) {
  8. if id == "" {
  9. return nil, errors.New("id is empty")
  10. }
  11. return s.repo.FindByID(id)
  12. }

✅ 对应点:

  • @Service → 结构体 + NewXXX
  • @Transactional → 手动 tx(Go 没有声明式事务)
  • 业务规则 → 全放 Service

3️⃣ Repository(数据层)

✅ Spring Boot

  1. @Repository
  2. public interface ArticleRepository {
  3. Article findById(String id);
  4. }

✅ Go

  1. type ArticleRepository struct {
  2. db *gorm.DB
  3. }
  4. func NewArticleRepository(db *gorm.DB) *ArticleRepository {
  5. return &ArticleRepository{db: db}
  6. }
  7. func (r *ArticleRepository) FindByID(id string) (*Article, error) {
  8. var article Article
  9. err := r.db.Where("id = ?", id).First(&article).Error
  10. return &article, err
  11. }

✅ 只做 CRUD,不写业务,和 Spring 的 Repository 完全一致。


4️⃣ Model / Entity

✅ Spring Boot

  1. @Entity
  2. public class Article {
  3. private String id;
  4. private String title;
  5. }

✅ Go

  1. type Article struct {
  2. ID string `json:"id"`
  3. Title string `json:"title"`
  4. }

✅ Go 的 struct = Java 的 entity / POJO


四、依赖注入(DI)对照(重点)

Spring Boot Go
@Autowired 构造函数参数
@ComponentScan 手动 NewXXX(...)
IoC 容器 wire(推荐)/ 手写

✅ Go 的“伪 DI”(非常 Spring)

  1. db := initDB()
  2. repo := NewArticleRepository(db)
  3. service := NewArticleService(repo)
  4. handler := NewArticleHandler(service)
  5. RegisterRoutes(router, handler)

👉 这就是 Go 的“控制反转”,不靠框架,靠代码清晰。


五、事务怎么写?(Go ≠ Spring)

Spring:

  1. @Transactional
  2. public void update() {}

Go:

  1. func (s *ArticleService) Update() error {
  2. tx := s.repo.db.Begin()
  3. defer tx.Rollback()
  4. // 业务逻辑
  5. return tx.Commit().Error
  6. }

✅ Go 没有 AOP,事务必须“显式写”,这也是 Go 的风格。


六、一句话总结这套映射

Spring Boot 是“框架帮你分层”,Go 是“你自己把分层写清楚”。
但只要你按 Handler → Service → Repository 走,
Go 项目就可以拥有 Spring Boot 一样的工程化结构。


七、你现在最值得做的事

如果你是从 PHP → Go + 想对 Java 平滑过渡,我建议你现在就:

  1. ✅ 用这套结构写一个 最小可用项目
  2. ✅ 刻意练习:Handler 不写 SQL
  3. ✅ 用 wire 或手写 DI,模拟 Spring 的注入
  4. ✅ SEO 页面用 html/template,API 用 JSON