怎么用golang实现基于注解的静态代码增强器/生成器
发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,本篇内容主要讲解"怎么用golang实现基于注解的静态代码增强器/生成器",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么用golang实现基于注解的静态
千家信息网最后更新 2025年11月07日怎么用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安全错误
数据库的锁怎样保障安全
邯郸前端软件开发公司
求生之路跳转服务器指令
安徽游戏软件开发公司排名
数据库实时到hbase查询
贵阳高新区华为软件开发平台
阿里软件开发p7岗位职责
cba广东数据库
互联网科技包装新闻
基岩版服务器假人插件
宠物救助数据库系统设计
大庆软件开发定制
计算机网络技术及应用学什么
业务数据库查询异常
绝地求生服务器
河源会计软件开发多少钱
成都软件开发的公司
来宾市网络安全十不准
长城开发服务器深圳
世界各国学术数据库
沈阳天机网络技术有限公司
美国高防服务器推荐
浪潮服务器连接路由器网口灯不亮
山西省ipfs服务器
网络安全青年力量微博
网络安全性能测试脚本
PHPWIND下载软件开发
对于软件开发的认知总结
bean查询数据库
苹果服务器王者下载
前端怎么维护数据库安全