如何使用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 enhancer import "learning/gooop/spring/autogen/domain" // IEnhancer clones the original file and appends enhanced code type IEnhancer interface { Matches(file *domain.CodeFileInfo) bool Enhance(file *domain.CodeFileInfo) (error, *domain.CodeFileInfo) }
enhancer/RestControllerEnhancer.goREST控制器的增强实现
package controller import ( "errors" "fmt" "learning/gooop/spring/autogen/domain" "path" "strings" ) type RestControllerEnhancer int type 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编写基于注解的静态代码增强器/生成器”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!
文章名称:如何使用golang编写基于注解的静态代码增强器/生成器
URL标题:http://azwzsj.com/article/gsggcd.html