Spring IOC 基础知识
IOC 就是依赖倒置原则的一种代码设计的思路。具体采用的方法就是所谓的依赖注入(Dependency Injection)。其实这些概念初次接触都会感到云里雾里的。说穿了,就是将对象的创建权,交给 Spring 容器管理。省去开发人员每次都去新建对象的烦恼。
手写 Spring IOC 容器
本章将实现一个基于 xml 配置的伪 Spring 容器,在该容器中,可以根据 bean 的 id 或 bean 的类型获取相应的 bean。
首先,建立一个 maven 工程,无需添加任何依赖。编写业务 Service 测试用例。
package com.yuxinglab.spring.ioc;
public class UserService {
private String msg;
public void sayMsg() {
System.out.println("你好:" + msg);
}
}
该类为业务 Service 的测试类,读者可自行扩展。
接下来,我们将开发自己的 IOC 容器,实现对业务 Bean 的管理。
package com.yuxinglab.spring.ioc;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class ApplicationContext {
private static Map beans = new HashMap();
static {
try {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder
.parse(ApplicationContext.class.getClassLoader().getResource("beans.xml").getPath());
Element documentElement = document.getDocumentElement();
NodeList childNodes = documentElement.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node item = childNodes.item(i);
if (item instanceof Element) {
Element element = (Element) item;
String id = element.getAttribute("id");
String aClass = element.getAttribute("class");
Class> target = Class.forName(aClass);
Object newInstance = target.newInstance();
NodeList property = element.getElementsByTagName("property");
for (int j = 0; j < property.getLength(); j++) {
Node node = property.item(j);
if (node instanceof Element) {
Element propertyElement = (Element) node;
String name = propertyElement.getAttribute("name");
String value = propertyElement.getAttribute("value");
Field field = target.getDeclaredField(name);
field.setAccessible(true);
field.set(newInstance, value);
}
}
beans.put(id, newInstance);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private ApplicationContext() {
}
public static Object getBeans(String id) {
return beans.get(id);
}
public static T getBeans(final Class cls) {
Collection values = beans.values();
for (Object obj : values) {
if (cls.isInstance(obj)) {
return (T) obj;
}
}
return null;
}
}
该类比较重要,说明如下: