github.com/zly-app/zapp@v1.3.3/config/watch.reset_obj_callback.go (about) 1 package config 2 3 import ( 4 "reflect" 5 ) 6 7 func init() { 8 AddResetInjectStructuredHook(resetInjectObjCallback) 9 } 10 11 type ResetInjectStructuredHook func(injectObj interface{}, newData []byte) (result interface{}, resultData []byte, cancel bool) 12 13 var resetInjectStructuredHooks []ResetInjectStructuredHook 14 15 // 添加重设注入结构拦截 16 func AddResetInjectStructuredHook(hooks ...ResetInjectStructuredHook) { 17 resetInjectStructuredHooks = append(resetInjectStructuredHooks, hooks...) 18 } 19 20 var resetInjectObjCallbacks = make(map[reflect.Type]func(injectObj interface{}, isField bool)) 21 22 /* 23 添加重设结构注入结构回调, 只有注入结构是指针才有效 24 25 如果注入结构实现了 T, 则会调用回调函数并传入注入结构的值, 其isField为false 26 如果注入结构是一个struct, 则会遍历其导出字段(包括继承)判断实现了 T , 则会调用回调函数并传入其字段的值, 其isField为true. 27 */ 28 func AddResetInjectObjCallback[T any](callback func(obj T, isField bool)) { 29 o := new(T) 30 rt := reflect.TypeOf(o).Elem() 31 resetInjectObjCallbacks[rt] = func(obj interface{}, isField bool) { 32 callback(obj.(T), isField) 33 } 34 } 35 36 func resetInjectObjCallback(injectObj interface{}, newData []byte) (result interface{}, resultData []byte, cancel bool) { 37 result = injectObj 38 resultData = newData 39 cancel = false 40 41 match := func(t reflect.Type, isField bool, get func() interface{}) { 42 for rt, callback := range resetInjectObjCallbacks { 43 if t.AssignableTo(rt) { 44 callback(get(), isField) 45 } 46 } 47 } 48 49 rv := reflect.ValueOf(injectObj) 50 if rv.Type().Kind() == reflect.Ptr { 51 match(rv.Type(), false, func() interface{} { 52 return rv.Interface() 53 }) 54 } 55 56 rv = reflect.Indirect(rv) 57 rt := rv.Type() 58 59 if rv.Kind() == reflect.Struct { 60 num := rt.NumField() 61 for i := 0; i < num; i++ { 62 ft := rt.Field(i) 63 if ft.PkgPath != "" || ft.Type.Kind() != reflect.Ptr { 64 continue 65 } 66 match(ft.Type, true, func() interface{} { 67 return rv.Field(i).Interface() 68 }) 69 } 70 } 71 return 72 }