使用Go语言的反射机制和函数类型实现AOP,通过在需要切入的函数前后添加额外的逻辑代码实现AOP
package main import ( "errors" "fmt" "log" "reflect" ) // User 结构体表示一个用户 type User struct { ID int Name string } type Aspect struct { Before []func([]reflect.Value) error After []func([]reflect.Value) error } // Apply 利用反射执行切面的前置和后置处理函数 func (a *Aspect) Apply(targetFunc interface{}, args []reflect.Value) ([]reflect.Value, error) { for _, beforeFunc := range a.Before { if err := beforeFunc(args); err != nil { return nil, err } } result := reflect.ValueOf(targetFunc).Call(args) for _, v := range result { if v.Type().AssignableTo(reflect.TypeOf((*error)(nil)).Elem()) { if v.IsNil() { continue } if err, ok := v.Interface().(error); ok { if err != nil { return nil, err } } else { log.Panicln("Failed to convert return value to error") } } } for _, afterFunc := range a.After { go afterFunc(args) } return result, nil } func BeforeAspect1(args []reflect.Value) error { id := args[0].Interface().(int) log.Println("BeforeAspect1 get id:", id) return nil } func BeforeAspect2(args []reflect.Value) error { name := args[1].Interface().(string) log.Println("BeforeAspect2 get name:", name) return nil } func BeforeAspect3(args []reflect.Value) error { user := args[2].Interface().(*User) log.Println("BeforeAspect3 get user:", user.ID, user.Name) return nil return errors.New("BeforeAspect3 error") } func AfterAspect1(args []reflect.Value) error { log.Println("AfterAspect1") return nil } func TargetFunction(id int, name string, user *User) (*User, error) { user.ID = 13 user.Name = "John Doe" fmt.Printf("Executing target function with ID: %d, Name: %s, User: %+v\n", id, name, user) return user, nil } func main() { myAspect := &Aspect{ Before: []func([]reflect.Value) error{ BeforeAspect1, BeforeAspect2, BeforeAspect3, }, After: []func([]reflect.Value) error{ AfterAspect1, }, } // 使用切面执行目标函数 targetFuncValue := reflect.ValueOf(TargetFunction) // 构造目标函数的参数值 id := 1 name := "John" user := &User{ID: 100, Name: "Alice"} args := []reflect.Value{ reflect.ValueOf(id), reflect.ValueOf(name), reflect.ValueOf(user), } result, err := myAspect.Apply(targetFuncValue.Interface(), args) if err != nil { fmt.Println("have err:", err) return } fmt.Println("Target function result:", result) }
上一篇:Django从入门到放弃