golang 代理实现 - Go语言中文社区

golang 代理实现


 拦截接口

#invocation_handler.go

package reflec

type InvocationHandler interface {
	Invoke(proxy *Proxy, method *Method, args []interface{}) ([]interface{}, error)
}

代理

#proxy.go

package reflec

import (
	"reflect"
	"fmt"
	"errors"
)

type Proxy struct {
	target  interface{}
	methods map[string]*Method
	handle  InvocationHandler
}


func New(target interface{}, h InvocationHandler) *Proxy {
	typ := reflect.TypeOf(target)
	value := reflect.ValueOf(target)
	methods := make(map[string]*Method, 0)
	for i := 0; i < value.NumMethod(); i++ {
		method := value.Method(i)
		methods[typ.Method(i).Name] = &Method{value:method}
	}
	return &Proxy{target:target, methods:methods, handle:h}
}

func (p *Proxy)InvokeMethod(name string, args ...interface{}) ([]interface{}, error) {
	return p.handle.Invoke(p, p.methods[name], args)
}


type Method struct {
	value reflect.Value
}

func (m *Method)Invoke(args ...interface{}) (res []interface{}, err error){
	defer func() {
		if p := recover(); p != nil {
			err = errors.New(fmt.Sprintf("%s", p))
		}
	}()
	params := make([]reflect.Value, 0)
	if args != nil {
		for i := 0; i < len(args); i++ {
			params = append(params, reflect.ValueOf(args[i]))
		}
	}
	res = make([]interface{}, 0)
	r := m.value.Call(params)
	if r != nil && len(r) > 0{
		for i := 0; i < len(r); i++ {
			res = append(res, r[i].Interface())
		}
	}
	return
}

测试 

#main.go

package main

import (
	_ "mmonitor/routers"
	"fmt"
	"mmonitor/reflec"
)




func main() {
	p := &Person{}
	h := new(PersonProxy)
	proxy := reflec.New(p,h)
	r ,_:= proxy.InvokeMethod("ReflectCallFuncNoArgs", 20, "sssssss")
	fmt.Println(r...)
	_, err := proxy.InvokeMethod("ReflectCallFuncNoArgs", 20, 323)
	fmt.Println(err)
}

type Person struct {

}

func (p *Person)ReflectCallFuncNoArgs(num int, num1 string) string {
	fmt.Println(num)
	fmt.Println(num1)
	return fmt.Sprintf("%d,%s", num, num1)
}


type PersonProxy struct {

}

func (p *PersonProxy)Invoke(proxy *reflec.Proxy, method *reflec.Method, args []interface{})([]interface{}, error){
    fmt.Println("begin")
	r , err:= method.Invoke(args...)
	fmt.Println("end")
	return r, err
}

结果

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_33240755/article/details/88351019
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-02-24 22:16:01
  • 阅读 ( 1345 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢