Spring学习笔记 第三章 Ioc底层原理

Spring学习笔记 第三章 Ioc底层原理

基本原理
・读取配置文件,解析XML
・通过反射机制实例化配置文件中所配置所有的bean

模拟实现底层处理

接口:ApplicationContext.java
	package com.hbb.Ioc;
	public interface ApplicationContext {
		public Object getBean(String id);
}
实现类:ClassPathXmlApplicationContext.java
package com.hbb.Ioc;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class ClassPathXmlApplicationContext implements ApplicationContext {

	private Map<String, Object> iocMap = new HashMap<String, Object>();

	public ClassPathXmlApplicationContext(String path) {
		try {
			// 通過reader取得spring.xml文件對象
			SAXReader reader = new SAXReader();
			Document document = reader.read(path);

			// 获取根节点
			Element root = document.getRootElement();

			// 遍历根节点
			Iterator<Element> iterator = root.elementIterator();
			while (iterator.hasNext()) {
				Element element = iterator.next();
				
				// 取得根节点bean的id和class
				String id = element.attributeValue("id");
				String className = element.attributeValue("class");

				// 通过反射机制创建对象
				Class cla = Class.forName(className);
				// 获取无参构造函数,创建目标对象
				Constructor constructor = cla.getConstructor();
				Object object = constructor.newInstance();

				// 给对象赋值
				Iterator<Element> beanIter = element.elementIterator();
				while (beanIter.hasNext()) {
					Element property = beanIter.next();
					
					// 取得属性
					String name = property.attributeValue("name");
					String valueStr = property.attributeValue("value");
					String ref = property.attributeValue("ref");
					
					if (ref == null) {
						// 作成set方法
						String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
						Field field = cla.getDeclaredField(name);
						Method method = cla.getDeclaredMethod(methodName, field.getType());

						Object value = null;
						// 根据成员变量的数据类型将value进行转换
						if (field.getType().getName() == "long") {
							value = Long.parseLong(valueStr);
						}
						if (field.getType().getName() == "java.lang.String") {
							value = valueStr;
						}
						if (field.getType().getName() == "int") {
							value = Integer.parseInt(valueStr);
						}
						method.invoke(object, value);
					}
					// 保存到iocMap
					iocMap.put(id, object);
				}
			}

		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public Object getBean(String id) {
		return iocMap.get(id);
	}
}
测试类:Test .java
package com.hbb.test;

import com.hbb.Ioc.ApplicationContext;
import com.hbb.Ioc.ClassPathXmlApplicationContext;
import com.hbb.entity.Student;

public class Test {
	public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("./src/main/resources/spring.xml");
		Student student = (Student) applicationContext.getBean("student");
		System.out.println(student);
	}
}
发布了12 篇原创文章 · 获赞 0 · 访问量 144

猜你喜欢

转载自blog.csdn.net/qq_41684416/article/details/105472023