怎么用golang实现基于注解的静态代码增强器/生成器
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,本篇内容主要讲解"怎么用golang实现基于注解的静态代码增强器/生成器",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么用golang实现基于注解的静态
千家信息网最后更新 2026年11月01日怎么用golang实现基于注解的静态代码增强器/生成器
本篇内容主要讲解"怎么用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编写"基于注解的静态代码增强器/生成器"
配置: ComponentScan,Configuration, Bean
Bean声明:Component, Service, Controller
Bean注入:Autowried
AOP注解:Before, After, Around, PointCut
子目标(Day 6)
昨天把思路撸清楚了,今天动手实现各种词法元素的扫描
project.go: 扫描整个项目的所有代码文件。module名从go.mod文件里面取
packages.go: 递归扫描某个代码目录
files.go: 扫描某个go代码文件,并解析import/struct/field/method等元素
imports: 扫描指定代码文件的所有import
domain/*.go:词法元素模型集,码略
project.go
扫描整个项目的所有代码文件。module名从go.mod文件里面取
package scannerimport ( "errors" "io/ioutil" "learning/gooop/spring/autogen/common" "learning/gooop/spring/autogen/domain" "os" "path" "strings")func ScanProject(name, dir string) (error, *domain.ProjectInfo) { e, module := parseModFileAndGetModuleName(dir) if e != nil { return e, nil } files, e := ioutil.ReadDir(dir) if e != nil { return e, nil } project := domain.NewProjectInfo() project.Name = name project.LocalDir = dir project.Module = module for _, file := range files { if !file.IsDir() { continue } e, pkg := ScanPackage(project, nil, dir+"/"+file.Name()) if e != nil { return e, nil } else { project.AppendPackage(pkg) } } return nil, project}func parseModFileAndGetModuleName(dir string) (error, string) { modfile := path.Join(dir, gModuleFile) _, e := os.Stat(modfile) if e != nil { return gErrorModuleFileNotFound, "" } data, e := ioutil.ReadFile(modfile) if e != nil { return e, "" } text := string(data) for _, line := range strings.Split(text, "\n") { line := strings.TrimSpace(line) if !common.Tokens.MatchString(line, gModulePrefix) { continue } if ok, s := common.Tokens.MatchRegexp(line, gModulePattern); ok { return nil, strings.TrimSpace(s[len(gModulePrefix)+1:]) } } return gErrorProjectModuleNotFound, ""}var gModuleFile = "go.mod"var gModulePrefix = "module"var gModulePattern = "^module\\s+\\w+(/\\w+)*"var gErrorModuleFileNotFound = errors.New("module file not found: go.mod")var gErrorProjectModuleNotFound = errors.New("project module not found in go.mod")packages.go
递归扫描某个代码目录
package scannerimport ( "io/ioutil" "learning/gooop/spring/autogen/domain" "path/filepath" "strings")func ScanPackage(project *domain.ProjectInfo, parent *domain.PackageInfo, dir string) (error, *domain.PackageInfo) { pkg := domain.NewPackageInfo() pkg.Project = project pkg.Parent = parent pkg.LocalDir = dir _, f := filepath.Split(dir) pkg.Name = f files, e := ioutil.ReadDir(dir) if e != nil { return e, nil } for _, file := range files { if file.IsDir() { e, p := ScanPackage(project, pkg, dir+"/"+file.Name()) if e != nil { return e, nil } else if p != nil { pkg.AppendPackage(p) } } else if strings.HasSuffix(file.Name(), ".go") { e, f := ScanCodeFile(pkg, dir+"/"+file.Name()) if e != nil { return e, nil } else if f != nil { pkg.AppendFile(f) } } } return nil, pkg}files.go
读入某个go代码文件,清除注释,然后解析import/struct/field/method等元素
package scannerimport ( "io/ioutil" "learning/gooop/spring/autogen/common" "learning/gooop/spring/autogen/domain" "regexp" "strings" "unicode")func ScanCodeFile(pkg *domain.PackageInfo, file string) (error, *domain.CodeFileInfo) { fbytes, e := ioutil.ReadFile(file) if e != nil { return e, nil } ftext := string(fbytes) lines := strings.Split(ftext, "\n") for i, it := range lines { lines[i] = strings.TrimRightFunc(it, unicode.IsSpace) } codeFile := domain.NewCodeFileInfo() codeFile.Package = pkg codeFile.RawLines = lines // clean comments bInParaComment := false cleanLines := make([]string, len(lines)) for i, it := range lines { s := it if bInParaComment { // para comment end? i := strings.Index(it, gParaCommentEnd) if i >= 0 { bInParaComment = false s = s[i+1:] } else { cleanLines[i] = "" continue } } if common.Tokens.MatchString(it, gLineCommentPrefix) { cleanLines[i] = "" continue } s = removeParaCommentInLine(it) i1 := strings.Index(s, gParaCommentStart) if i1 >= 0 { s = s[:i1] bInParaComment = true } cleanLines[i] = s } // parse imports ScanImport(codeFile) // todo: parse struct declares/fields/methods return nil, nil}func removeParaCommentInLine(s string) string { arr := gParaCommentInLine.FindAllStringIndex(s, -1) if len(arr) > 0 { for i := len(arr) - 1; i >= 0; i-- { from := arr[i][0] to := arr[i][1] s = s[:from] + s[to+1:] } } return s}var gLineCommentPrefix = "^\\s*//"var gParaCommentInLine = regexp.MustCompile("/\\*.*\\*/")var gParaCommentStart = "/*"var gParaCommentEnd = "*/"imports.go
扫描指定代码文件的所有import
package scannerimport ( "learning/gooop/spring/autogen/domain" "regexp")func ScanImport(file *domain.CodeFileInfo) { parseSingleImport(file) parseMultiImports(file)}func parseSingleImport(file *domain.CodeFileInfo) { for _, it := range file.CleanLines { if gSingleImportRegexp.MatchString(it) { ss := gSingleImportRegexp.FindAllStringSubmatch(it, -1)[0] imp := domain.NewImportInfo() imp.File = file if len(ss) == 3 { imp.Alias = "" imp.Package = ss[1] } else if len(ss) == 5 { imp.Alias = ss[1] imp.Package = ss[3] } file.AppendImport(imp) } }}func parseMultiImports(file *domain.CodeFileInfo) { bInBlock := false for _, it := range file.CleanLines { if bInBlock { if gMultiImportEnd.MatchString(it) { bInBlock = false continue } if gImportPackage.MatchString(it) { ss := gImportPackage.FindAllStringSubmatch(it, -1)[0] imp := domain.NewImportInfo() imp.File = file if len(ss) == 3 { imp.Alias = "" imp.Package = ss[1] } else if len(ss) == 5 { imp.Alias = ss[2] imp.Package = ss[3] } } } if gMultiImportStart.MatchString(it) { bInBlock = true continue } }}var gSingleImportRegexp = regexp.MustCompile(`\s*import\s+((\w+|\.)\s+)?("\w+(/\w+)*")`)var gMultiImportStart = regexp.MustCompile(`^\s*import\s+\(`)var gMultiImportEnd = regexp.MustCompile(`^\s*\)`)var gImportPackage = regexp.MustCompile(`^\s*((\w+|\.)\s+)?("\w+(/\w+)*")`)到此,相信大家对"怎么用golang实现基于注解的静态代码增强器/生成器"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
代码
文件
注解
生成器
静态
增强器
生成
元素
内容
目录
目标
词法
项目
递归
学习
实用
更深
清楚
兴趣
切面
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
苏州找大状互联网科技有限公司
今日互联网科技
广州宏创互联网科技
互联网科技论坛
成都狮子座互联网科技
互联网科技中介
互联网科技项目计划书材料类
科技互联网大厂
呼和浩特新华互联网科技学院
开一家科技互联网公司需要多少钱
米聚互联网科技南京有限公司排面
互联网新科技动漫ppt素材
黑科技 体验场景 互联网大会
杭州披云加互联网科技有限公司
世界互联网科技成果奖
互联网科技机房
上海万顺科技互联网有限公司招聘
互联网金融运营模式中的金融科技
现代互联网科技公司
广州全民伙伴互联网科技有限公司
湖南永感互联网科技有限公司
苏州找大状互联网科技有限公司
西安互联网科技
以房互联网科技
互联网 科技服务平台
互联网科技生活的内容
互联网之后的科技是什么
福州新华互联网科技学校 知乎
华夏互联网科技业
互联网高科技绘画