Skip to content

go_aop 是一个go语言实现aop功能的包,主要参考gin框架中的拦截器实现,具有对核心方法拦截,过滤的功能

Notifications You must be signed in to change notification settings

hourongjia/go_aop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

简介

go_aop 是一个go语言实现aop功能的包,主要参考gin框架中的拦截器实现,具有对核心方法拦截,过滤的功能

使用方法

步骤1:用户确定要拦截或者过滤的方法或者函数

var f2 = func(ctx context.Context, param ...go_aop.CustomizeParam) {
	fmt.Println("handle f2")
}

go_aop.CustomizeParam是一个接口,如果用户被拦截的方法需要传入自定义的上下文,需要实现go_aop.CustomizeParam,比如,针对maia,maia的上下文变量是maia.Action:

type MaiaCustomizeParam struct {
	action maia.Action // 这里定义你自己需要的上下文参数,比如string或者你自己定义的action
}

func (receiver MyCustomizeParam) CustomizeContext() map[string]interface{} {
	p := map[string]interface{}{
		"maiaAction": receiver.action,
	}
	return p
}

随后,用户可以在执行方法f2的方法中,获取到action对象

var f2 = func(ctx context.Context, param ...go_aop.CustomizeParam) {
    map := param[0].CustomizeContext()       
    action := map["maiaAction"]                //获取用户被拦截方法自己的上下文
    action.Do()                                //执行上下文方法
	fmt.Println("handle f2")
}

步骤2:实例化go_aop.WrapF对象

func WrapFunc(f func(ctx context.Context, param ...CustomizeParam), ctx context.Context, param ...CustomizeParam) *WrapF 

步骤3:实现拦截或者过滤函数

当用户希望实现过滤操作的时候,

func XXX(c *go_aop.Context) {
   fmt.Println("前置操作")
   c.Next()  //过滤功能用c.Next()方法,表示继续执行函数
   fmt.Println("后置操作")
}

当用户希望实现拦截操作的时候,

func XXX(c *go_aop.Context) {
   fmt.Println("前置操作")
   c.Abort()  //过滤功能用c.Abort()方法,表示不会执行下个拦截器的方法
   fmt.Println("后置操作")
}

当用户希望将拦截器或者过滤器中写入变量到上下文中,并且全局可读,可以如下demo所示:


func AFilter(c *go_aop.Context) {
   fmt.Println("A前置操作")
   c.Ctx = context.WithValue(c.Ctx,"key","value")  //写入上下文变量
   c.Next()  //过滤功能用c.Abort()方法,表示不会执行下个拦截器的方法
   fmt.Println(c.Ctx.Value("key"))                 // 同一个过滤器中读取之前写入上下文变量
   fmt.Println("A后置操作")
}

func BFilter(c *go_aop.Context) {
   fmt.Println("B前置操作")
   c.Next()  //过滤功能用c.Abort()方法,表示不会执行下个拦截器的方法
   fmt.Println(c.Ctx.Value("key"))                 // 不同过滤器读取之前写入上下文变量
   fmt.Println("B后置操作")
}


如果用户希望过滤器中的上下文变量不共享,即A过滤器只能读到A的上下文变量,B的过滤器只能读到b的上线文变量,如下操作:


func AFilter(c *go_aop.Context) {
   fmt.Println("A前置操作")
   ctx := c.Ctx
   ctx = context.WithValue(ctx,"key","value")  //写入上下文变量
   c.Next()  //过滤功能用c.Abort()方法,表示不会执行下个拦截器的方法
   fmt.Println(ctx.Value("key"))                 // 同一个过滤器中读取之前写入上下文变量,可以读取到
   fmt.Println("A后置操作")
}

func BFilter(c *go_aop.Context) {
   fmt.Println("B前置操作")
   c.Next()  //过滤功能用c.Abort()方法,表示不会执行下个拦截器的方法
   fmt.Println(c.Ctx.Value("key"))                 // 不同过滤器读取之前写入上下文变量,无法读取到数据
   fmt.Println("B后置操作")
} 

即不要将withValue完的context写回c.Ctx

步骤4:将步骤2的函数加入到wrap对象中

eg:

    ctx := context.Background()
	wrapF := go_aop.WrapFunc(f2, ctx)
	// 绑定limit
	wrapF.Use(limitRate)
	wrapF.Use(AbortAdapt)

步骤5:调用wrap对象的Handle方法,开始执行

eg:

    ctx := context.Background()
	wrapF := go_aop.WrapFunc(f2, ctx)
	wrapF.Use(limitRate)
	wrapF.Use(AbortAdapt)
	// 执行handler方法
	wrapF.Handle()

完成,用户可以参考源代码中的common_test.go文件,里边有详细的测试demo和使用demo,欢迎使用

About

go_aop 是一个go语言实现aop功能的包,主要参考gin框架中的拦截器实现,具有对核心方法拦截,过滤的功能

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages