手动实现简单的IOC容器

IOC概述

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

实现IOC容器

依赖

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.2.0</version>
</dependency>

编写beans.xml

然后使用Dom4J解析编写的xml文件,如下格式

1
2
3
4
<?xml version="1.0" encoding="UTF-8" ?>
<beans>
<bean id="hello" class="pojo.User"/>
</beans>

新建BeanFactory类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private static final Map<String, Object> IOC = new HashMap<>();

static {
try {
//加载配置文件
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml");
SAXReader reader = new SAXReader();
Document document = reader.read(in);
//xpath
String xpath = "//bean";
List<Element> list = document.selectNodes(xpath);
for (Element element : list) {
String id = element.attributeValue("id");
String aClass = element.attributeValue("class");
Object o = Class.forName(aClass).getDeclaredConstructor().newInstance();
IOC.put(id, o);
}
} catch (Exception e) {
e.printStackTrace();
}
}

使用一个Map来存储对象,然后在类的静态代码块中读取并解析xml,使用反射加载每一个类并放入Map容器中

编写getBean方法

1
2
3
public static Object getBean(String name) {
return IOC.get(name);
}

编写一个获取bean的类方法用来从容器中获取Bean

测试

1
2
3
public static void main(String[] args) {
User user = BeanFactory.getBean("hello", User.class);
}

成功获取到bean

虽然有些警告,但也无伤大雅哈哈

最后给出全部代码

User类定义

1
2
3
4
5
public class User {
public User() {
System.out.println("User初始化");
}
}

BeanFactory

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
package config;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author Fairy
* @date 2021/11/7
*/
@SuppressWarnings("unchecked")
public class BeanFactory {

private static final Map<String, Object> IOC = new HashMap<>();


static {
try {
//加载配置文件
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml");
SAXReader reader = new SAXReader();
Document document = reader.read(in);
//xpath
String xpath = "//bean";
List<Element> list = document.selectNodes(xpath);
for (Element element : list) {
String id = element.attributeValue("id");
String aClass = element.attributeValue("class");
Object o = Class.forName(aClass).getDeclaredConstructor().newInstance();
IOC.put(id, o);
}
} catch (Exception e) {
e.printStackTrace();
}
}

public static <T> T getBean(String name, Class<T> clazz) {
return (T)IOC.get(name);
}

public static Object getBean(String name) {
return IOC.get(name);
}
}