千家信息网

怎么使用golang仿spring ioc/aop基于注解的静态代码增强器/生成器

发表于:2024-10-27 作者:千家信息网编辑
千家信息网最后更新 2024年10月27日,这篇文章主要介绍"怎么使用golang仿spring ioc/aop基于注解的静态代码增强器/生成器",在日常操作中,相信很多人在怎么使用golang仿spring ioc/aop基于注解的静态代码增
千家信息网最后更新 2024年10月27日怎么使用golang仿spring ioc/aop基于注解的静态代码增强器/生成器

这篇文章主要介绍"怎么使用golang仿spring ioc/aop基于注解的静态代码增强器/生成器",在日常操作中,相信很多人在怎么使用golang仿spring ioc/aop基于注解的静态代码增强器/生成器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"怎么使用golang仿spring ioc/aop基于注解的静态代码增强器/生成器"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

手撸golang spring ioc/aop 之2

Spring

Spring基于J2EE技术实现了一套轻量级的Java Web Service系统应用框架。它有很多优秀的特性,很多公司都选择把Spring作为产品或项目的基础开发架构。Spring的特性包括轻量、控制反转(Inversion of Control, IoC)、面向容器、面向切面(AspectOriented Programming, AOP)和框架灵活等。源码gitee地址:https://gitee.com/ioly/learning.gooop原文链接:https://my.oschina.net/ioly

目标

  • 参考spring常用注解,使用golang编写"基于注解的静态代码增强器/生成器"

    • 配置: ComponentScan,Configuration, Bean

    • Bean声明:Component, Service, Controller

    • Bean注入:Autowried

    • AOP注解:Before, After, Around, PointCut

子目标(Day 2)

  • 构思app的运行模式:

    • 本地standlone模式运行

    • 提供基于cli的命令行实时交互

    • 生成旁路代码:只扫描源代码,不修改源代码,增强后的代码加统一后缀

  • 设计cli交互指令集:

    • config save:保存配置

    • config saveas :另存配置

    • watch add

      :添加代码扫描目录

    • watch del

      :移除代码扫描目录

    • watch list:显示当前扫描的代码目录集合

    • gen:生成增强代码,也就是扫描所有注解,并生成增强类和增强方法

设计

  • config/IConfiguration:配置接口

  • command/ICmd:指令接口

  • command/ICmdBuilder:指令构建器接口

  • command/ICmdContext:指令执行上下文接口

  • config_cmd/SaveCmd: 保存配置

  • config_cmd/SaveASCmd: 另存配置

  • watch_cmd/AddCmd: 添加监视

  • watch_cmd/DelCmd: 移除监视

  • watch_cmd/ListCmd: 显示已监视目录的列表

  • gen_cmd/GenCmd: 生成增强类和增强方法

  • model/IEventDrivenModel:"事件驱动"的逻辑编排模型

  • logger: 日志接口,略

config/IConfiguration.go

配置接口

package config// IConfiguration defines system configuration interfacetype IConfiguration interface {        GetProjectName() string        SetProjectName(string)        GetWatchPaths() []string        AddWatchPath(string)        DelWatchPath(string)        Save() error        SaveAS(string) error}

command/ICmd.go

指令接口

package commandimport "fmt"// ICmd defines cli command interfacetype ICmd interface {        fmt.Stringer        // Apply apply current command into use        Apply(ICmdContext) error}

command/ICmdBuilder.go

指令构建器接口

package command// ICmdBuilder parse input string and create an ICmd instancetype ICmdBuilder interface {        Build(string) (error, ICmd)}

command/ICmdContext.go

指令执行上下文接口

package commandimport "learning/gooop/spring/autogen/config"// ICmdContext provides context info for all commandstype ICmdContext interface {        GetConfiguration() config.IConfiguration}

config_cmd/SaveCmd.go

保存配置

package config_cmdimport (        "learning/gooop/spring/autogen/command")// SaveCmd calls service.Save() to save current configuration, in JSON formattype SaveCmd int// SaveCmdBuilder parse cli input and build a SaveCmd instancetype SaveCmdBuilder intconst gSaveCmdString = "config save"var gSaveCmdInstance = new(SaveCmd)func (me *SaveCmd) String() string {        return gSaveCmdString}func (me *SaveCmd) Apply(c command.ICmdContext) error {        // todo: fixme        panic("implements me")}func (me *SaveCmdBuilder) Build(line string) (error, command.ICmd) {        if line != gSaveCmdString {                return nil, nil        }        return nil, gSaveCmdInstance}

config_cmd/SaveASCmd.go

另存配置

package config_cmdimport (        "errors"        "learning/gooop/spring/autogen/command"        "strings")// SaveASCmd calls service.SaveAS() to save current config into specific file, in JSON formattype SaveASCmd struct {        file string}// SaveASCmdBuilder parse cli input and returns a SaveASCmd instancetype SaveASCmdBuilder intconst gSaveASCmdPrefix = "config saveas "func (me *SaveASCmd) String() string {        return gSaveASCmdPrefix + me.file}func (me *SaveASCmd) Apply(c command.ICmdContext) error {        // todo: fixme        panic("implements me")}func (me *SaveASCmdBuilder) Build(line string) (error, command.ICmd) {        if !strings.HasPrefix(line, gSaveASCmdPrefix) {                return nil, nil        }        file := strings.TrimSpace(line[len(gSaveASCmdPrefix):])        if len(file) <= 0 {                return errors.New("empty file path"), nil        }        return nil, &SaveASCmd{file }}

watch_cmd/AddCmd.go

添加监视

package watch_cmdimport (        "learning/gooop/spring/autogen/command"        "os"        "strings")// AddCmd calls service.WatchAdd() to add dir to watch listtype AddCmd struct {        dir string}type AddCmdBuilder intvar gAddCmdPrefix = "watch add "func (me *AddCmd) String() string {        return gAddCmdPrefix + me.dir}func (me *AddCmd) Apply(c command.ICmdContext) error {        // todo: fixme        panic("implements me")}func (me *AddCmdBuilder) Build(line string) (error, command.ICmd) {        // check prefix        if !strings.HasPrefix(line, gAddCmdPrefix) {                return nil, nil        }        // get dir        dir := strings.TrimSpace(line[len(gAddCmdPrefix):])        // check dir        _,e := os.Stat(dir)        if e != nil {                return e, nil        }        // ok        return nil, &AddCmd{dir }}

watch_cmd/DelCmd.go

移除监视

package watch_cmdimport (        "learning/gooop/spring/autogen/command"        "os"        "strings")// DelCmd calls service.WatchDel() to remove dir from watch listtype DelCmd struct {        dir string}type DelCmdBuilder intvar gDelCmdPrefix = "watch del "func (me *DelCmd) String() string {        return gDelCmdPrefix + me.dir}func (me *DelCmd) Apply(c command.ICmdContext) error {        // todo: fixme        panic("implements me")}func (me *DelCmdBuilder) Build(line string) (error, command.ICmd) {        // check prefix        if !strings.HasPrefix(line, gDelCmdPrefix) {                return nil, nil        }        // get dir        dir := strings.TrimSpace(line[len(gAddCmdPrefix):])        // check dir        _,e := os.Stat(dir)        if e != nil {                return e, nil        }        // ok        return nil, &DelCmd{ dir }}

watch_cmd/ListCmd.go

显示已监视目录的列表

package watch_cmdimport (        "learning/gooop/spring/autogen/command")// ListCmd calls service.WatchListtype ListCmd int// ListCmdBuilder parse cli input and try to build a ListCmd instancetype ListCmdBuilder intconst gListCmdString1 = "watch list"const gListCmdString2 = "watch ls"var gListCmdSingleton = new(ListCmd)func (me *ListCmd) String() string {        return gListCmdString1}func (me *ListCmd) Apply(c command.ICmdContext) error {        // todo:        panic("implements me")}func (me *ListCmdBuilder) Build(line string) (error, command.ICmd) {        if line != gListCmdString1 && line != gListCmdString2 {                return nil, nil        }        return nil, gListCmdSingleton}

gen_cmd/GenCmd.go

生成增强类和增强方法

package gen_cmdimport (        "learning/gooop/spring/autogen/command")// GenCmd calls service.Gen() to generate enhanced code files at oncetype GenCmd int// GenCmdBuilder parse cli input and try to build a GenCmd instancetype GenCmdBuilder intconst gGenCmdString = "gen"var gGenCmdSingleton = new(GenCmd)func (me *GenCmd) String() string {        return gGenCmdString}func (me *GenCmd) Apply(c command.ICmdContext) error {        panic("implements me")}func (me *GenCmdBuilder) Build(line string) (error, command.ICmd) {        if line != gGenCmdString {                return nil, nil        }        return nil, gGenCmdSingleton}

model/IEventDrivenModel.go

"事件驱动"的逻辑编排模型

package model// IEventDrivenModel defines an event driven model for code arrangementtype IEventDrivenModel interface {        Hook(e string, handleFunc TEventHandleFunc)        Fire(e string, args ...interface{})        FireAsync(e string, args ...interface{})}type TEventHandleFunc func(e string, args ...interface{})type TEventDrivenModel struct {        items map[string][]TEventHandleFunc}func (me *TEventDrivenModel) Hook(e string, handler TEventHandleFunc) {        if me.items == nil {                me.items = make(map[string][]TEventHandleFunc)        }        arr, ok := me.items[e]        if ok {                me.items[e] = append(arr, handler)        } else {                me.items[e] = []TEventHandleFunc{handler}        }}func (me *TEventDrivenModel) Fire(e string, args ...interface{}) {        if handlers, ok := me.items[e]; ok {                for _, it := range handlers {                        it(e, args...)                }        }}func (me *TEventDrivenModel) FireAsync(e string, args ...interface{}) {        go me.Fire(e, args...)}

到此,关于"怎么使用golang仿spring ioc/aop基于注解的静态代码增强器/生成器"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0