手写spring ioc
原理
- 容器:本质是一个map,核心功能 : 1.存对象(Bean)2.取对象 (按名称或类型获取Bean)3.管理依赖(自动注入所需Bean)
- IOC: IoC(控制反转)就是把对象的创建和依赖管理交给容器,而不是在代码里手动
new
对象 - DI:DI(依赖注入)是 IoC(控制反转)的实现方式,指的是由容器自动将对象的依赖注入进去,而不是手动创建。由容器来决定对象之间的依赖关系
步骤
- 解析xml
plaintext
1 | public void parseXml() { |
- 创建空的bean对象在容器中 plaintext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public void newBean() {
Set<Map.Entry<String, ClassBean>> entries = classbeanMap.entrySet();
beanMap = new HashMap<>();
for (Map.Entry<String, ClassBean> entry : entries) {
ClassBean classBean = entry.getValue();
String className = classBean.ClassName;
String name = classBean.name;
// 实例化对象
try {
Object o = Class.forName(className).getDeclaredConstructor().newInstance();
beanMap.put(name, o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
} - 依赖注入 plaintext
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
59public void dependencyInjection() {
Set<Map.Entry<String, ClassBean>> entries = classbeanMap.entrySet();
for (Map.Entry<String, ClassBean> entry : entries) {
//获取bean信息
ClassBean classBean = entry.getValue();
String name = classBean.getName();
Map<String, Property> propertyMap = classBean.getPropertyMap();
//获得空的bean对象
Object o = beanMap.get(name);
//将属性注入bean
Set<Map.Entry<String, Property>> entries1 = propertyMap.entrySet();
for (Map.Entry<String, Property> stringPropertyEntry : entries1) {
//如果需要访问特定索引,先将entries1转为List
Property property = stringPropertyEntry.getValue();
String proName = property.getName();
String proValue = property.getValue();
String proRef = property.getRef();
if (proRef != null) {
// 获得需要引用的对象
Object refBean = beanMap.get(proRef);
try {
// 反射动态获取 根据proName的不同,set名称也不同
String SetMethod = "set" + proName.substring(0, 1).toUpperCase() + proName.substring(1);
Method method = o.getClass().getMethod(SetMethod, refBean.getClass());
method.invoke(o, refBean);
} catch (Exception e) {
throw new RuntimeException(e);
}
} else if (proValue != null) {
try {
// 获得属性名
Field valueField = o.getClass().getDeclaredField(proName);
// 反射动态获取 根据proName的不同,set名称也不同
String SetMethod = "set" + proName.substring(0, 1).toUpperCase() + proName.substring(1);
Method method = o.getClass().getMethod(SetMethod, valueField.getType());
// 判断属性类型,从而转换
Class<?> valueFieldType = valueField.getType();
if (valueFieldType == int.class || valueFieldType == Integer.class) {
int valueCast = Integer.parseInt(proValue);
method.invoke(o, valueCast);
} else if (valueFieldType == Float.class || valueFieldType == float.class) {
float valueCast2 = Float.parseFloat(proValue);
method.invoke(o, valueCast2);
} else if (valueFieldType == double.class || valueFieldType == Double.class) {
double valueCast3 = Double.parseDouble(proValue);
method.invoke(o, valueCast3);
}else {
method.invoke(o, proValue);
}
} catch(Exception e){
throw new RuntimeException(e);
}
}
}
}
}
不足
- aop
- 注解
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.