学习 Spring,跟着二哥简单写个 IoC 容器。

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
@Target(ElementType.FIELD)  
@Retention(RetentionPolicy.RUNTIME)
@interface MyAutowired {
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface MyComponent {
}

public class SimpleIoC {
Map<Class<?>, Object> beans = new HashMap<>();

//扫描
public void scan(String packageName) {
List<Class<?>> classes = getClassesInPackage(packageName);
for (Class<?> clazz : classes) {
if (clazz.isAnnotationPresent(MyComponent.class)) {
registerBean(clazz);
}
}
di();
}

//获取包下的类,简化实现
private List<Class<?>> getClassesInPackage(String packageName) {
// 实际实现需要扫描classpath,这里简化处理.
return Arrays.asList(UserDao.class, UserService.class);
}

//注册bean
private void registerBean (Class<?> clazz) {
try {
Object instance = clazz.getDeclaredConstructor().newInstance();
beans.put(clazz, instance);
} catch (Exception e) {
throw new RuntimeException("创建bean失败");
}
}
//获取bean
@SuppressWarnings("unchecked")
public <T> T getBean(Class<T> clazz) {
return (T)beans.get(clazz);
}
//依赖注入
private void di() {
for (Object bean : beans.values()) {
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(MyAutowired.class)) {
field.setAccessible(true);
Object dependency = getBean(field.getType());
try {
field.set(bean, dependency);
} catch (Exception e) {
throw new RuntimeException("依赖注入失败");
}
}
}
}
}
}
//DAO层
@MyComponent
class UserDao {
public void save(String user) {
System.out.println("保存用户: " + user);
}
}

// Service层
@MyComponent
class UserService {
@MyAutowired
private UserDao userDao;

public void createUser(String name) {
userDao.save(name);
System.out.println("用户创建完成");
}
}

class Test {
public static void main(String[] args) {
SimpleIoC ioc = new SimpleIoC();
ioc.scan("package");
UserService bean = ioc.getBean(UserService.class);
bean.createUser("dong");
}
}

参考链接:

二哥的Java进阶之路

Java反射 | withdong02

Java泛型 | withdong02