本篇内容介绍了“如何使用golang编写基于注解的静态代码增强器/生成器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
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编写“基于注解的静态代码增强器/生成器”
编写针对@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.go REST控制器的增强实现
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编写基于注解的静态代码增强器/生成器”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/ioly/blog/5025314