实现简单的 IOC 和 AOP
1.1 简单的 IOC 容器实现的步骤
-
加载 xml 配置文件,遍历其中的标签
-
获取标签中的 id 和 class 属性,加载 class 属性对应的类,并创建 bean
-
遍历标签中的标签,获取属性值,并将属性值填充到 bean中
-
将 bean 注册到 bean 容器中
1.2 代码结构
SimpleIOC // IOC 的实现类,实现了上面说的四个步骤
SimpleIOCTest // IOC 的测试类
Car // IOC 测试使用的bean
Wheel // 同上
ioc.xml(放到源代码目录下) // bean 配置文件
1.3 使用到的技术
-
加载xml配置文件,使用org.w3c.dom包下的Document等类来遍历其中的标签
-
beanClass = Class.forName(className) ==> beanClass.newInstance();
-
反射:利用反射将 bean 相关字段访问权限设为可访问,将属性值填充到相关字段中
-
使用HashMap 模拟 bean 容器
1.4 代码
容器实现类 SimpleIOC 的代码:
package ioc;
public class SimpleIOC {
private Map<String, Object> beanMap = new HashMap<String, Object>();
public SimpleIOC(String location) throws Exception {
loadBeans(location);
}
public Object getBean(String name) {
Object bean = beanMap.get(name);
if (bean == null) {
throw new IllegalArgumentException("there is no bean with name: " + name);
}
return bean;
}
private void loadBeans(String location) throws Exception {
// 加载 xml 配置文件
System.out.println(location);
InputStream inputStream = new FileInputStream(location);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = factory.newDocumentBuilder();
Document document = docBuilder.parse(inputStream);
Element root = document.getDocumentElement();
NodeList nodes = root.getChildNodes();
// 遍历 <bean> 标签
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
String id = ele.getAttribute("id");
String className = ele.getAttribute("class");
// 加载 beanClass
Class beanClass = null;
try {
beanClass = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}
// 创建 bean
Object bean = beanClass.newInstance();
// 遍历 <property> 标签
NodeList propertyNodes = ele.getElementsByTagName("property");
for (int j = 0; j < propertyNodes.getLength(); j++) {
Node propertyNode = propertyNodes.item(j);
if (propertyNode instanceof Element) {
Element propertyElement = (Element) propertyNode;