千家信息网

如何使用golang编写基于注解的静态代码增强器/生成器

发表于:2025-01-21 作者:千家信息网编辑
千家信息网最后更新 2025年01月21日,本篇内容介绍了"如何使用golang编写基于注解的静态代码增强器/生成器"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅
千家信息网最后更新 2025年01月21日如何使用golang编写基于注解的静态代码增强器/生成器

本篇内容介绍了"如何使用golang编写基于注解的静态代码增强器/生成器"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

Spring

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

目标

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

子目标(Day 11)

  • 编写针对@RestController的增强器

    • enhancer/IEnhancer.go: 定义增强器接口

    • enhancer/RestControllerEnhancer.go:REST控制器的增强实现

enhancer/IEnhancer.go: 定义增强器接口

package enhancerimport "learning/gooop/spring/autogen/domain"// IEnhancer clones the original file and appends enhanced codetype IEnhancer interface {        Matches(file *domain.CodeFileInfo) bool        Enhance(file *domain.CodeFileInfo) (error, *domain.CodeFileInfo)}

enhancer/RestControllerEnhancer.go REST控制器的增强实现

package controllerimport (        "errors"        "fmt"        "learning/gooop/spring/autogen/domain"        "path"        "strings")type RestControllerEnhancer inttype tMappingMethodInfo struct {        httpMethod string        httpPath   string        method     *domain.MethodInfo}func (me *RestControllerEnhancer) Matches(file *domain.CodeFileInfo) bool {        for _, it := range file.Structs {                if ok, _ := me.hasAnnotation(it.Annotations, "RestController"); ok {                        return true                }        }        return false}func (me *RestControllerEnhancer) Enhance(file *domain.CodeFileInfo) (error, *domain.CodeFileInfo) {        // clone file        file = file.Clone().(*domain.CodeFileInfo)        file.LocalFile = strings.Replace(file.LocalFile, ".go", "_Enhanced.go", -1)        // find structs with @RestController        changed := false        for _, it := range file.Structs {                if ok, a := me.hasAnnotation(it.Annotations, "RestController"); ok {                        // enhance target struct                        e := me.enhanceStruct(it, a)                        if e != nil {                                return e, nil                        }                        changed = true                }        }        if changed {                return nil, file        } else {                return nil, nil        }}func (me *RestControllerEnhancer) hasAnnotation(arr []*domain.AnnotationInfo, name string) (bool, *domain.AnnotationInfo) {        for _, it := range arr {                if it.Name == name {                        return true, it                }        }        return false, nil}func (me *RestControllerEnhancer) enhanceStruct(s *domain.StructInfo, sa *domain.AnnotationInfo) error {        // update struct name        s.Name = s.Name + "_Enhanced"        // ensure imports        me.ensureImport(s.CodeFile, "github.com/gin-gonic/gin")        me.ensureImport(s.CodeFile, "net/http")        // enhance GetMapping methods        methods := []*tMappingMethodInfo{}        for _, it := range s.Methods {                if ok, a := me.hasAnnotation(it.Annotations, "GetMapping"); ok {                        e := me.enhanceGetMapping(it, a)                        if e != nil {                                return e                        }                        info := new(tMappingMethodInfo)                        info.httpMethod = "GET"                        info.httpPath = path.Join(sa.Get("path"), a.Get("path"))                        info.method = it                        methods = append(methods, info)                }        }        // enhance PostMapping methods        for _, it := range s.Methods {                if ok, a := me.hasAnnotation(it.Annotations, "PostMapping"); ok {                        e := me.enhancePostMapping(it, a)                        if e != nil {                                return e                        }                        info := new(tMappingMethodInfo)                        info.httpMethod = "POST"                        info.httpPath = path.Join(sa.Get("path"), a.Get("path"))                        info.method = it                        methods = append(methods, info)                }        }        // generate RegisterRestController()        if len(methods) <= 0 {                return errors.New("no mapping method found")        }        file := s.CodeFile        addLine := func(line string) {                file.AdditionalLines = append(file.AdditionalLines, line)        }        addLine(`// RegisterRestController is auto generated to implements controller.IRestController interface`)        addLine(fmt.Sprintf(`func (me *%s) RegisterRestController(r *gin.Engine) {`, s.Name))        for _, it := range methods {                addLine(fmt.Sprintf(`  r.%s("%s", me.%s)`, it.httpMethod, it.httpPath, it.method.Name))        }        addLine(`}`)        return nil}func (me *RestControllerEnhancer) ensureImport(file *domain.CodeFileInfo, p string) {        for _, it := range file.Imports {                if it.Package == p {                        return                }        }        // add import info        it := new(domain.ImportInfo)        it.CodeFile = file        it.Package = p        file.AdditionalImports = append(file.AdditionalImports, it)}func (me *RestControllerEnhancer) enhanceGetMapping(method *domain.MethodInfo, a *domain.AnnotationInfo) error {        // todo: fixme        panic("implements me")}func (me *RestControllerEnhancer) enhancePostMapping(method *domain.MethodInfo, a *domain.AnnotationInfo) error {        // todo: fixme        panic("implements me")}

"如何使用golang编写基于注解的静态代码增强器/生成器"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0