這裏寫自定義目錄標題
SpringIOC的簡單實現
1. spring IOC簡介
ioc: 全文是Inversion of Control。翻譯過來就是控制反轉,意思是對象之間的關係不再由傳統的程序來控制,而是由spring容器來統一控制這些對象創建、協調、銷燬,而對象只需要完成業務邏輯即可。
2. IOC的簡單實現
- 加載 xml 配置文件,遍歷其中的標籤
- 獲取標籤中的 id 和 class 屬性,加載 class 屬性對應的類,並創建 bean
- 遍歷標籤中的標籤,獲取屬性值,並將屬性值填充到 bean 中
- 將 bean 註冊到 bean 容器中
測試使用的實體類一 :Car
/**
* @author crazyang
* @date 2019/8/21
* @Description:
*/
public class Car {
private String name;
private String length;
private String width;
private String height;
private Wheel wheel;
//省略getter/setter
}
測試使用的實體類二:Wheel
/**
* @author crazyang
* @date 2019/8/21
* @Description:
*/
public class Wheel {
private String brand;
private String specification;
//省略getter/setter
}
springIoc的簡單實現類
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* @author crazyang
* @date 2019/8/21
* @Description:
*/
public class SimpleIOC {
private Map<String, Object> beanMap = new HashMap<>();
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配置文件
InputStream inputStream = new FileInputStream(location);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = factory.newDocumentBuilder();
Document doc = docBuilder.parse(inputStream);
Element root = doc.getDocumentElement();
NodeList nodes = root.getChildNodes();
//遍歷<bean>標籤
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node instanceof Element) {
Element element = (Element) node;
String id = element.getAttribute("id");
String className = element.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 = element.getElementsByTagName("property");
for (int j = 0; j < propertyNodes.getLength(); j++) {
Node propertyNode = propertyNodes.item(j);
if (propertyNode instanceof Element) {
Element propertyElement = (Element) propertyNode;
String name = propertyElement.getAttribute("name");
String value = propertyElement.getAttribute("value");
//利用反射將bean相關字段訪問權限設爲可訪問
Field declareField = bean.getClass().getDeclaredField(name);
declareField.setAccessible(true);
if (value != null && value.length() > 0) {
declareField.set(bean, value);
} else {
String ref = propertyElement.getAttribute("ref");
if (ref == null && ref.length() == 0) {
throw new IllegalArgumentException("ref config error");
}
//將引用填充到相關字段中
declareField.set(bean, getBean(ref));
}
//將bean註冊到bean容器中
registerBean(id, bean);
}
}
}
}
}
private void registerBean(String id, Object bean) {
beanMap.put(id, bean);
}
}
springIOC的配置文件,路徑是放在resource下面
<beans>
<bean id="wheel" class="com.yangzhou.utils.Spring.ioc.Wheel">
<property name="brand" value="Michelin"/>
<property name="specification" value="265/60 R18"/>
</bean>
<bean id="car" class="com.yangzhou.utils.Spring.ioc.Car">
<property name="name" value="Mercedes Benz G 500"/>
<property name="length" value="4717mm"/>
<property name="width" value="1855mm"/>
<property name="height" value="1949mm"/>
<property name="wheel" ref="wheel"/>
</bean>
</beans>
springIoc的測試類
/**
* @author zhouyang
* @date 2019/8/21
* @Description:
*/
public class SpringIOCTest {
public static void main(String[] args)throws Exception {
String path = "D:\\project\\test\\utils\\src\\main\\resources\\spring-test.xml";
String location = SpringIOCTest.class.getClassLoader().getResource("spring-test.xml").getFile();
SimpleIOC bf = new SimpleIOC(location);
Wheel wheel = (Wheel) bf.getBean("wheel");
System.out.println(wheel);
Car car = (Car) bf.getBean("car");
System.out.println(car);
System.out.println(car.getName());
}
}
輸出結果:
com.yangzhou.utils.Spring.ioc.Wheel@5a07e868
com.yangzhou.utils.Spring.ioc.Car@76ed5528
Mercedes Benz G 500