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的生命周期管理

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