缘起

最近阅读 [Spring Boot技术内幕: 架构设计与实现原理] (朱智胜 , 2020.6)
本系列笔记拟采用golang练习之
Talk is cheap, show me the code.

Spring

  1. Spring的主要特性:
  2. 1. 控制反转(Inversion of Control, IoC
  3. 2. 面向容器
  4. 3. 面向切面(AspectOriented Programming, AOP
  5. 源码gitee地址:
  6. https://gitee.com/ioly/learning.gooop
  7. 原文链接:
  8. https://my.oschina.net/ioly

目标

  • 参考spring boot常用注解,使用golang编写“基于注解的静态代码增强器/生成器”

子目标(Day 12)

  • 昨天的增强代码太不oo了,今天添加接口封装:
    • domain/ICodeGenerator: 定义代码生成器接口
    • generator/ImportGenerator: import语句的生成器
    • generator/ParamDTOGenerator: get/post参数DTO结构体的生成器
    • generator/MappingMethodGenerator: 增强GetMapping/PostMapping方法的生成器

domain/CodeFileInfo

代码文件模型

  1. package domain
  2. type CodeFileInfo struct {
  3. Package *PackageInfo `json:"-"`
  4. LocalFile string
  5. RawLines []string
  6. CleanLines []string
  7. Imports []*ImportInfo
  8. Structs []*StructInfo
  9. AdditionalLines []ICodeGenerator
  10. }

domain/ICodeGenerator.go

定义代码生成器接口

  1. package domain
  2. import (
  3. "fmt"
  4. )
  5. type ICodeGenerator interface {
  6. fmt.Stringer
  7. Section() CodeSection
  8. }

generator/ImportGenerator.go

import语句的生成器

  1. package generator
  2. import (
  3. "fmt"
  4. "learning/gooop/spring/autogen/domain"
  5. )
  6. type ImportGenerator struct {
  7. Package string
  8. Alias string
  9. }
  10. func (me *ImportGenerator) String() string {
  11. if me.Alias != "" {
  12. return fmt.Sprintf(`import %s %s`, me.Alias, me.Package)
  13. } else {
  14. return fmt.Sprintf(`import %s`, me.Package)
  15. }
  16. }
  17. func (me *ImportGenerator) Section() domain.CodeSection {
  18. return domain.ImportSection
  19. }

generator/ParamDTOGenerator.go

get/post参数DTO结构体的生成器

  1. package generator
  2. import (
  3. "fmt"
  4. "learning/gooop/spring/autogen/domain"
  5. "strings"
  6. )
  7. type ParamsDTOGenerator struct {
  8. Method *domain.MethodInfo
  9. }
  10. func NewParamsDTOGenerator(m *domain.MethodInfo) domain.ICodeGenerator {
  11. it := new(ParamsDTOGenerator)
  12. it.Method = m
  13. return it
  14. }
  15. func (me *ParamsDTOGenerator) Section() domain.CodeSection {
  16. return domain.AnywhereSection
  17. }
  18. func (me *ParamsDTOGenerator) String() string {
  19. lines := []string{}
  20. fnAddLinef := func(f string, args... interface{}) {
  21. lines = append(lines, fmt.Sprintf(f, args...))
  22. }
  23. fnAddLinef(``)
  24. // declare
  25. name := fmt.Sprintf(`%s_%s_ParamsDTO`, me.Method.Struct.Name, me.Method.Name)
  26. fnAddLinef(`// %s is auto generated struct for wrapping parameters of PagedQuery`, name)
  27. fnAddLinef(`type %s struct {`, name)
  28. // fields
  29. for _,a := range me.Method.Arguments {
  30. fnAddLinef(` %s %s`, strings.Title(a.Name), a.DataType)
  31. }
  32. // end
  33. fnAddLinef("}")
  34. // return
  35. return strings.Join(lines, "\n")
  36. }

generator/MappingMethodGenerator.go

增强GetMapping/PostMapping方法的生成器

  1. package generator
  2. import (
  3. "fmt"
  4. "learning/gooop/spring/autogen/domain"
  5. )
  6. type MappingMethodGenerator struct {
  7. Method *domain.MethodInfo
  8. }
  9. func (me *MappingMethodGenerator) Section() domain.CodeSection {
  10. return domain.AnywhereSection
  11. }
  12. func (me *MappingMethodGenerator) String() string {
  13. lines := []string{}
  14. fnAddLinef := func(f string, args... interface{}) {
  15. lines = append(lines, fmt.Sprintf(f, args...))
  16. }
  17. fnAddLinef(``)
  18. fnAddLinef(`// %s_Enhanced is the enhanced version of PagedQuery`, me.Method.Name)
  19. fnAddLinef(`func (me *%s) %s_Enhanced(c *gin.Context) {`, me.Method.Struct.Name, me.Method.Name)
  20. // todo: fixme
  21. //r := new(OrderController_Query_ParamsDTO)
  22. //e := c.Bind(r)
  23. //if e != nil {
  24. // c.JSON(http.StatusBadRequest, gin.H{"ok": false, "error": e.Error()})
  25. // return
  26. //}
  27. //
  28. //e, d := me.Query(r.CustomerID, r.StatusFlag, r.DateFrom, r.DateTO, r.PageNO, r.PageSize)
  29. //if e != nil {
  30. // c.JSON(http.StatusInternalServerError, gin.H{"ok": false, "error": e.Error()})
  31. // return
  32. //}
  33. //
  34. //c.JSON(http.StatusOK, gin.H{"ok": true, "data": d})
  35. //}
  36. return ""
  37. }

(未完待续)