IOC原理

一、 什么是依赖注入

一个类依赖于另一个类,被依赖的类不是通过直接new出来的,而是通过某种方法传入的,那就是注入。类Student依赖于类School

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class School {
String name = "BeiJing university";
String getName() {
return name;
}
}

class Student {
School school;
}

public class App {
public static void main(String[] args) {
Student student = new Student();
System.Out.Println(student.school.name);
}
}

在上面的程序中,报错,因为school没有创建。

二、如何注入

既然是注入,那么肯定是有个第三方,第三方把被依赖的类创建后,然后注入到依赖类中。新增一个第三方。使用自动注入需要使用到的知识有,1:泛型类,2:反射 3:注解

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
import java.lang.annotation.*;
import java.lang.reflect.*;

// 一个注解 如果标记了该注解,就表示标注的对象是需要自动注入的
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface AutoWired {}

// 一个被依赖的对象
class School {
String name = "BeiJing university";
String getName() {
return name;
}
}

// 一个依赖对象
class Student {
@AutoWired // 新增一个注解,作用是标记,这个属性需要被自动注入
School school;

String name;
}

// 一个代理类
class Factory {
public <T> create(Class className) {
T cls = (T) className.newInstance();

/*== 开始注入, 问题是,如何知道哪些熟悉是需要注入的,1.获取所有属性,2.查看该熟悉是否有需要自动注入的标记,而这里的标记就是注解 ==*/

// 获取属性
Field[] fields = className.getDeclaredFields();
for ( Field field : fields) {
// 获取某属性 注解
Annotation[] annotations = field.getAnnotations();
for (Annotation an : annotions) {
// 判断是否含有 AutoWired注解
if (an.annotationType == AutoWired.class) {
// 使用反射创建实例 并自动注入
field.set(cls, field.getType().newInstance())
}
}
}
// 使用反射获取所有属性
return cls;
}
}

public class App {
public static void main(String[] args) {
Factory<Student> factory = new Factory<Student>();
Student student = (Student) factory.create(Student.class)
System.Out.Println(student.school.name);
}
}

原本一个new就能解决的问题,为什么搞得这么麻烦呢

如何创建单列模式呢