怎么用golang实现基于注解的静态代码增强器/生成器
发表于:2025-02-08 作者:千家信息网编辑
千家信息网最后更新 2025年02月08日,本篇内容主要讲解"怎么用golang实现基于注解的静态代码增强器/生成器",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么用golang实现基于注解的静态
千家信息网最后更新 2025年02月08日怎么用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安全错误
数据库的锁怎样保障安全
增城网络安全哪家强
电力组态软件开发
爆骗子数据库
益诚 深圳 软件开发
广州通信网络技术
杭州学习软件开发哪家有名
服务器管理包括哪些品牌
凤凰网读书软件开发
宝塔 设置数据库
系统 更改数据库文件
smb服务器是指什么
阿里云的云数据库储存技术
web服务器性能测试工具
管理软件开发一体化
阿里云的数据库安全等级保护
网络技术服务的成本有哪些
宁波信息化网络技术费用是多少
校园园网络安全实施方案
杭州语音聊天软件开发
刀塔传奇服务器一键端
网络技术措施的建议
短信服务器如何连接电脑
无线网络安全性差原因
kali 远程连接nas服务器
哪些证可以考网络安全
dw怎么连接sql数据库
四川服务器虚拟化定做
江苏计算机网络技术学习科目
长宁区散射网络技术供应
429网络安全图片