手撸golang仿springioc/aop之12增强3

ioly      2022-02-12     632

关键词:

手撸golang 仿spring ioc/aop 之12 增强3

缘起

最近阅读 [Spring Boot技术内幕: 架构设计与实现原理] (朱智胜 , 2020.6)
本系列笔记拟采用golang练习之
Talk is cheap, show me the code.

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编写“基于注解的静态代码增强器/生成器”

子目标(Day 12)

  • 昨天的增强代码太不oo了,今天添加接口封装:

    • domain/ICodeGenerator: 定义代码生成器接口
    • generator/ImportGenerator: import语句的生成器
    • generator/ParamDTOGenerator: get/post参数DTO结构体的生成器
    • generator/MappingMethodGenerator: 增强GetMapping/PostMapping方法的生成器

domain/CodeFileInfo

代码文件模型

package domain

type CodeFileInfo struct {
    Package    *PackageInfo `json:"-"`
    LocalFile  string
    RawLines   []string
    CleanLines []string
    Imports    []*ImportInfo
    Structs    []*StructInfo

    AdditionalLines   []ICodeGenerator
}

domain/ICodeGenerator.go

定义代码生成器接口

package domain

import (
    "fmt"
)

type ICodeGenerator interface {
    fmt.Stringer
    Section() CodeSection
}

generator/ImportGenerator.go

import语句的生成器

package generator

import (
    "fmt"
    "learning/gooop/spring/autogen/domain"
)

type ImportGenerator struct {
    Package string
    Alias string
}


func (me *ImportGenerator) String() string {
    if me.Alias != "" {
        return fmt.Sprintf(`import %s %s`, me.Alias, me.Package)
    } else {
        return fmt.Sprintf(`import %s`, me.Package)
    }
}

func (me *ImportGenerator) Section() domain.CodeSection {
    return domain.ImportSection
}

generator/ParamDTOGenerator.go

get/post参数DTO结构体的生成器

package generator

import (
    "fmt"
    "learning/gooop/spring/autogen/domain"
    "strings"
)

type ParamsDTOGenerator struct {
    Method *domain.MethodInfo
}

func NewParamsDTOGenerator(m *domain.MethodInfo) domain.ICodeGenerator {
    it := new(ParamsDTOGenerator)
    it.Method = m
    return it
}


func (me *ParamsDTOGenerator) Section() domain.CodeSection {
    return domain.ImportSection
}

func (me *ParamsDTOGenerator) String() string {
    lines := []string{}
    fnAddLinef := func(f string, args... interface{}) {
        lines = append(lines, fmt.Sprintf(f, args...))
    }

    fnAddLinef(``)

    // declare
    name := fmt.Sprintf(`%s_%s_ParamsDTO`, me.Method.Struct.Name, me.Method.Name)
    fnAddLinef(`// %s is auto generated struct for wrapping parameters of PagedQuery`, name)
    fnAddLinef(`type %s struct {`, name)

    // fields
    for _,a := range me.Method.Arguments {
        fnAddLinef(`    %s %s`, strings.Title(a.Name), a.DataType)
    }

    // end
    fnAddLinef("}")

    // return
    return strings.Join(lines, "\n")
}

generator/MappingMethodGenerator.go

增强GetMapping/PostMapping方法的生成器

package generator

import (
    "fmt"
    "learning/gooop/spring/autogen/domain"
)

type MappingMethodGenerator struct {
    Method *domain.MethodInfo
}


func (me *MappingMethodGenerator) Section() domain.CodeSection {
    return domain.AnywhereSection
}

func (me *MappingMethodGenerator) String() string {
    lines := []string{}
    fnAddLinef := func(f string, args... interface{}) {
        lines = append(lines, fmt.Sprintf(f, args...))
    }

    fnAddLinef(``)

    fnAddLinef(`// %s_Enhanced is the enhanced version of PagedQuery`, me.Method.Name)
    fnAddLinef(`func (me *%s) %s_Enhanced(c *gin.Context) {`, me.Method.Struct.Name, me.Method.Name)

    // todo: fixme

        //r := new(OrderController_Query_ParamsDTO)
        //e := c.Bind(r)
        //if e != nil {
        //    c.JSON(http.StatusBadRequest, gin.H{"ok": false, "error": e.Error()})
        //    return
        //}
        //
        //e, d := me.Query(r.CustomerID, r.StatusFlag, r.DateFrom, r.DateTO, r.PageNO, r.PageSize)
        //if e != nil {
        //    c.JSON(http.StatusInternalServerError, gin.H{"ok": false, "error": e.Error()})
        //    return
        //}
        //
        //c.JSON(http.StatusOK, gin.H{"ok": true, "data": d})
    //}

    return ""
}

(未完待续)

手撸golang仿springioc/aop之5如何扫描

手撸golang仿springioc/aop之5如何扫描缘起最近阅读[SpringBoot技术内幕:架构设计与实现原理](朱智胜,2020.6)本系列笔记拟采用golang练习之Talkischeap,showmethecode.SpringSpring的主要特性:1.控制反转(InversionofControl,IoC)2.面向容器3.面向切面(... 查看详情

手撸golang学etcd手写raft协议之12单元测试

手撸golang学etcd手写raft协议之12单元测试缘起最近阅读[云原生分布式存储基石:etcd深入解析](杜军,2019.1)本系列笔记拟采用golang练习之raft分布式一致性算法分布式存储系统通常会通过维护多个副本来进行容错,以提高系统的可用... 查看详情

手撸golangspringioc/aop之2

手撸golangspringioc/aop之2缘起最近阅读[Offer来了:Java面试核心知识点精讲(框架篇)](王磊,2020.6)本系列笔记拟采用golang练习之Talkischeap,showmethecode.SpringSpring基于J2EE技术实现了一套轻量级的JavaWebService系统应用框架。它有很多优秀的... 查看详情

手撸golangetcdraft协议之11

手撸golangetcdraft协议之11缘起最近阅读[云原生分布式存储基石:etcd深入解析](杜军,2019.1)本系列笔记拟采用golang练习之raft分布式一致性算法分布式存储系统通常会通过维护多个副本来进行容错,以提高系统的可用性。这就引出了... 查看详情

手撸golangspringioc/aop之2

参考技术A手撸golangspringioc/aop之2最近阅读[Offer来了:Java面试核心知识点精讲(框架篇)](王磊,2020.6)本系列笔记拟采用golang练习之Talkischeap,showmethecode.配置接口指令接口指令构建器接口指令执行上下文接口保存配置另存配置添加... 查看详情

手撸golanggo与微服务chatserver之1

缘起最近阅读<<Go微服务实战>>(刘金亮,2021.1)本系列笔记拟采用golang练习之案例需求(聊天服务器)用户可以连接到服务器。用户可以设定自己的用户名。用户可以向服务器发送消息,同时服务器也会向其他用户广播该消息... 查看详情

手撸golanggo与微服务saga模式之1

缘起最近阅读<<Go微服务实战>>(刘金亮,2021.1)本系列笔记拟采用golang练习之Saga模式saga模式将分布式长事务切分为一系列独立短事务每个短事务是可通过补偿动作进行撤销的事务动作和补偿动作都是幂等的,允许重复执行而... 查看详情

手撸golanggo与微服务saga模式之7

缘起最近阅读<<Go微服务实战>>(刘金亮,2021.1)本系列笔记拟采用golang练习之Saga模式saga模式将分布式长事务切分为一系列独立短事务每个短事务是可通过补偿动作进行撤销的事务动作和补动作偿都是幂等的,允许重复执行而... 查看详情

手撸golang行为型设计模式模板方法模式

手撸golang行为型设计模式模板方法模式缘起最近复习设计模式拜读谭勇德的<<设计模式就该这样学>>本系列笔记拟采用golang练习之模板方法模式模板方法模式(TemplateMethodPattern)又叫作模板模式,指定义一个操作中的算... 查看详情

手撸golang基本数据结构与算法队列

手撸golang基本数据结构与算法队列缘起最近阅读<<我的第一本算法书>>(【日】石田保辉;宫崎修一)本系列笔记拟采用golang练习之队列队列中的数据也呈线性排列。队列中添加和删除数据的操作分别是在两端进行的。就和... 查看详情

手撸golanggo与微服务chatserver之3压测与诊断

缘起最近阅读<<Go微服务实战>>(刘金亮,2021.1)本系列笔记拟采用golang练习之案例需求(聊天服务器)用户可以连接到服务器。用户可以设定自己的用户名。用户可以向服务器发送消息,同时服务器也会向其他用户广播该消息... 查看详情

手撸golang行为型设计模式访问者模式

手撸golang行为型设计模式访问者模式缘起最近复习设计模式拜读谭勇德的<<设计模式就该这样学>>本系列笔记拟采用golang练习之访问者模式访问者模式(VisitorPattern)是一种将数据结构与数据操作分离的设计模式,指封装... 查看详情

手撸golang基本数据结构与算法冒泡排序

缘起最近阅读<<我的第一本算法书>>(【日】石田保辉;宫崎修一)本系列笔记拟采用golang练习之冒泡排序冒泡排序就是重复“从序列右边开始比较相邻两个数字的大小,再根据结果交换两个数字的位置”这一操作的算法。... 查看详情

手撸golang基本数据结构与算法归并排序

缘起最近阅读<<我的第一本算法书>>(【日】石田保辉;宫崎修一)本系列笔记拟采用golang练习之归并排序归并排序算法会把序列分成长度相同的两个子序列,当无法继续往下分时(也就是每个子序列中只有一个数据时),... 查看详情

goroutine并发调度模型深度解析之手撸一个协程池(代码片段)

golanggoroutine协程池GroutinePool高并发并发(并行),一直以来都是一个编程语言里的核心主题之一,也是被开发者关注最多的话题;Go语言作为一个出道以来就自带『高并发』光环的富二代编程语言,它的并发(并行)编程肯定是... 查看详情

手撸golang基本数据结构与算法网页排名/pagerank,随机游走

缘起最近阅读<<我的第一本算法书>>(【日】石田保辉;宫崎修一)本系列笔记拟采用golang练习之网页排名(PageRank/佩奇排名),随机游走网页排名(PageRank,也叫作佩奇排名)是一种在搜索网页时对搜索结果进行排序的算法。... 查看详情

手撸系列之——orm(对象关系映射)(代码片段)

ORM:对象关系映射类》》》数据库的一张表对象》》》表的一条记录对象点属性》》》记录某一个字段对应的值废话不多少,先上代码:#orm.pyfrommysql_singletionimportMysql#设置表字段类,通常需要的属性为字段名,字段类型,是否为... 查看详情

十三.netty入门到超神系列-手撸简单版rpc框架(仿dubbo)(代码片段)

...xff0c;为了加强对Netty的理解,这篇文章我们来仿照dubbo手撸一个简易版本的RPC框架结构理解先来看一张图原理还是比较简单:代理+线程池+Netty下面做一些解释:首先需要定义一个统一的API接口,例:UserApi,服务... 查看详情