This repository has been archived by the owner on Mar 10, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdefinition.go
149 lines (133 loc) · 3.35 KB
/
definition.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package bean
import (
"fmt"
"reflect"
)
// 依赖场景类型
const (
PROTOTYPE = "prototype"
SINGLETON = "singleton"
)
// NewReflect 创建反射
func NewReflect(i interface{}) func() reflect.Value {
switch reflect.TypeOf(i).Kind() {
case reflect.Func:
return func() reflect.Value {
return reflect.ValueOf(i)
}
case reflect.Struct:
return func() reflect.Value {
return reflect.New(reflect.TypeOf(i))
}
default:
panic("Invalid type, use only func and struct")
}
return nil
}
// ConstructorArgs 构造器参数
type ConstructorArgs []interface{}
// Fields 字段
type Fields map[string]interface{}
// Reference 引用
type Reference struct {
Name string
}
// NewReference 创建引用
func NewReference(name string) Reference {
return Reference{Name: name}
}
// ReturnError 返回错误
type ReturnError struct {
error
}
// NewReturnError 创建返回错误
func NewReturnError(err error) *ReturnError {
return &ReturnError{err}
}
// BeanDefinition 依赖定义
type BeanDefinition struct {
Name string
Reflect func() reflect.Value
Scope string
InitMethod string
ConstructorArgs ConstructorArgs
Fields Fields
context *ApplicationContext
}
// Refresh 刷新
func (t *BeanDefinition) Refresh() {
if t.Scope != SINGLETON {
return
}
t.context.instances.Store(t.Name, t.instance())
}
// 实例化
func (t *BeanDefinition) instance() interface{} {
v := t.Reflect()
// 构造器注入
if v.Kind() == reflect.Func {
in := []reflect.Value{}
for _, a := range t.ConstructorArgs {
// 引用字段处理
if _, ok := a.(Reference); ok {
a = t.context.GetBean(a.(Reference).Name, Fields{}, ConstructorArgs{})
}
in = append(in, reflect.ValueOf(a))
}
func() {
defer func() {
if err := recover(); err != nil {
if err, ok := err.(*ReturnError); ok {
panic(err)
}
panic(fmt.Sprintf("Bean name '%s' reflect %s construct failed, %s", t.Name, v.Type().String(), err))
}
}()
res := v.Call(in)
if len(res) >= 2 {
if err, ok := res[1].Interface().(error); ok {
panic(NewReturnError(err))
}
}
v = res[0]
}()
if v.Kind() == reflect.Struct {
panic(fmt.Sprintf("Bean name '%s' reflect %s return value is not a pointer type", t.Name, v.Type().String()))
}
}
// 字段注入
for k, p := range t.Fields {
// 字段检测
if !v.Elem().FieldByName(k).CanSet() {
panic(fmt.Sprintf("Bean name '%s' type %s field %s cannot be found or cannot be set", t.Name, reflect.TypeOf(v.Interface()), k))
}
// 引用字段处理
if _, ok := p.(Reference); ok {
p = t.context.GetBean(p.(Reference).Name, Fields{}, ConstructorArgs{})
}
// 类型检测
if v.Elem().FieldByName(k).Type().String() != reflect.TypeOf(p).String() {
panic(fmt.Sprintf("Bean name '%s' type %s field %s value of type %s is not assignable to type %s",
t.Name,
reflect.TypeOf(v.Interface()),
k,
reflect.TypeOf(p).String(), v.Elem().FieldByName(k).Type().String()),
)
}
// 常规字段处理
v.Elem().FieldByName(k).Set(reflect.ValueOf(p))
}
// 执行初始化方法
if t.InitMethod != "" {
m := v.MethodByName(t.InitMethod)
if !m.IsValid() {
panic(fmt.Sprintf("Bean name '%s' type %s init method %s not found",
t.Name,
reflect.TypeOf(v.Interface()),
t.InitMethod,
))
}
m.Call([]reflect.Value{})
}
return v.Interface()
}