spring如何實現IOC和DI思想?

spring的兩大思想,IOC和AOP,IOC實現對象的創建和生命週期管理,AOP面向切面編程,將和業務邏輯沒有直接關聯的業務代碼從主業務代碼中抽離出來,需要的時候再切入進去,實現程序的可插拔和弱耦合.
spring根據一個配置文件就能幫助我們創建對象,並注入屬性.於是乎,就自己寫個程序去解析xml,根據裏面的配置,往類裏面的屬性注入值,最終實現的效果是這樣的:
輸出結果
Step1:新建一個配置文件applicationContext.xml,當然不叫這個名也是可以的.
配置文件
Step2:創建兩個實體,Person和Dog

public class Dog {
	private String type;
	private String color;
	@Override
	public String toString() {
		return "Dog [type=" + type + ", color=" + color + "]";
	}
	public void setType(String type) {
		this.type = type;
	}
	public void setColor(String color) {
		this.color = color;
	}
}
public class Person {
	private String name;
	private Integer age;
	private Dog dog;
	public void setName(String name) {
		this.name = name;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public void setDog(Dog dog) {
		this.dog = dog;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", dog=" + dog + "]";
	}
	
}

重寫toString()方法,目的是讓打印結果更直接;
Step3:核心程序,解析xml,往兩個實體注入屬性,廉頗老將軍不僅能喫飯還左牽黃右擎蒼~

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.util.Objects;
import javax.xml.parsers.DocumentBuilderFactory;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class SpringMockTest {

	@Test
	public void testSpringMock() throws Exception {
		// 加載xml文件
		String path = Objects.requireNonNull(SpringMockTest.class.getClassLoader().getResource("applicationContext.xml")).getPath();
		File file = new File(path);
		// 解析文件成DOM
		Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
		// 獲取根元素
		Element rootEle = document.getDocumentElement();
		// 獲取所有的bean元素對象
		NodeList beans = rootEle.getElementsByTagName("bean");
		Element personBeanEle = (Element) beans.item(0);
		// 獲取person元素的屬性值
		NodeList PersonBeanProperties = personBeanEle.getElementsByTagName("property");
		Element personBeanPropEle1 = (Element) PersonBeanProperties.item(0);
		Element personBeanPropEle2 = (Element) PersonBeanProperties.item(1);
		Element personBeanPropEle3 = (Element) PersonBeanProperties.item(2);
		// 獲取Person的字節碼對象
		Class<?> personClz = Class.forName(personBeanEle.getAttribute("class"));
		Object person = personClz.newInstance();
		// 獲取Person的屬性描述器
		PropertyDescriptor[] personPds = Introspector.getBeanInfo(personClz, Object.class).getPropertyDescriptors();
		//運用內省機制注入屬性值
		for (PropertyDescriptor personPd : personPds) {
			if (personPd.getName().equals(personBeanPropEle1.getAttribute("name"))) {
				personPd.getWriteMethod().invoke(person, personBeanPropEle1.getAttribute("value"));
			} else if (personPd.getName().equals(personBeanPropEle2.getAttribute("name"))) {
				personPd.getWriteMethod().invoke(person, Integer.parseInt(personBeanPropEle2.getAttribute("value")));
			} else {
				Object dog = null;
				for (int i = 0; i < beans.getLength(); i++) {
					Element beanEle = (Element) beans.item(i);
					if (personBeanPropEle3.getAttribute("ref").equals(beanEle.getAttribute("id"))) {
            //通過反射獲得dog對象
						Class<?> dogClz = Class.forName(beanEle.getAttribute("class"));
						dog = dogClz.newInstance();
            //獲取dog對象的屬性節點列表
						NodeList dogBeanProperties = beanEle.getElementsByTagName("property");
            //獲取dog對象屬性描述器
						PropertyDescriptor[] dogPds = Introspector.getBeanInfo(dogClz, Object.class).getPropertyDescriptors();
						for (PropertyDescriptor dogPd : dogPds) {
							for (int j = 0; j < dogBeanProperties.getLength(); j++) {
								Element dogBeanPropEle = (Element)dogBeanProperties.item(j);
								if (dogPd.getName().equals(dogBeanPropEle.getAttribute("name"))) {
                  //如果xml中屬性名和dog對象屬性名一致,則注入值
									dogPd.getWriteMethod().invoke(dog, dogBeanPropEle.getAttribute("value"));
								}
							}
						}
					}
				}
        //同理,person對象注入相應屬性值
				personPd.getWriteMethod().invoke(person, dog);
			}
		}
		System.out.println(person);
	}

}

到此就結束了,代碼很簡單,主要是理解一遍spring IOC思想.
spring對bean進行實例化,默認bean是單例.
通過查看源碼我發現spring實現了很多的BeanPostProcessor,來實現對象生命週期的管理,有張圖可以參考下:
spring對bean的生命週期管理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章