Spring原理自我实践之IOC的模拟实现

    在学习Spring的过程中,为了更加透彻的理解IOC容器,在讲师的分析下,自我实践了一下IOC的模拟实现:
Class_1:核心的模拟IOC类,其中注释已经十分清晰

package com.java.mySpring;

import java.util.HashMap;
import java.util.Map;

import com.java.util.AnalyzeXMLUtil;
import com.java.util.ReflectHelper;

/**
 * 实例说明:模拟IOC的原理
 * 
 * @author citizen
 * 
 */
public class MyIOC {
	// 配置文件的绝对路径
	private static final String XML_PATH = "F:/eclipse-jee-ganymede-SR2-win32(1)/project/MyIOC/src/beans.xml";
	private Map<String, Object> beansMap = new HashMap<String, Object>();// 模拟存储对象的Map容器

	/**
	 * 创建IOC容器
	 * 
	 * @throws Exception
	 */
	private void creatIOC() throws Exception {
		// 取得配置文件中所有的bean,将id为key创建在Map中
		String[] ids = AnalyzeXMLUtil.getAttributeValue(XML_PATH,
				"/beans/bean", "id");
		for (int i = 0; i < ids.length; i++) {
			createBean(ids[i]);
		}
	}

	/**
	 * 在容器初始化时,载入对象
	 * 
	 * @throws Exception
	 */
	@SuppressWarnings("static-access")
	public MyIOC() throws Exception {
		creatIOC();
	}

	/**
	 * 创建Bean在容器里
	 * 
	 * @param beanId
	 *            Bean的Id
	 * @return
	 * @throws Exception
	 */
	private Object createBean(String beanId) throws Exception {
		// TODO Auto-generated method stub
		String className = AnalyzeXMLUtil.getSingleAttributeValue(XML_PATH,"/beans/bean[@id='" + beanId + "']", "class");
		Object[] args = new Object[0];
		Object bean = null;
		// 如果已存在该对象,直接返回该对象
		if (beansMap.containsKey(beanId)) {
			return beansMap.get(beanId);
		} else {// 如果不存在,创建对象
			bean = ReflectHelper.newInstance(className, args);
		}
//取得某一个Bean所有的属性名
		String[] propNames = AnalyzeXMLUtil.getAttributeValue(XML_PATH,"/beans/bean[@id='" + beanId + "']/property", "name");
		for (int j = 0; j < propNames.length; j++) {
			//取得某一个Bean对应的所有属性的值
			String propValue = AnalyzeXMLUtil.getSingleAttributeValue(XML_PATH,
					"/beans/bean[@id='" + beanId + "']/property[@name='"
							+ propNames[j] + "']", "value");
			// 如果Bean的属性是基本类型,注入该属性值
			if (propValue != null && propValue.length() > 0) {
				/*
				 * Object[] setArgs = new Object[1]; setArgs[0] = propValue;
				 * ReflectHelper.invokeMethod(bean,
				 * ReflectHelper.getSetMethodNameByFieldName(propNames[j]),
				 * setArgs);
				 */
				ReflectHelper.setFieldValue(bean, propNames[j], propValue);
			}
			// 如果Bean的属性是引用Bean,可能要递归创建依赖的Bean
			else {
				propValue = AnalyzeXMLUtil.getSingleAttributeValue(XML_PATH,"/beans/bean[@id='" + beanId + "']/property[@name='"
								+ propNames[j] + "']", "ref");
				Object dependBean = createBean(propValue);//递归调用
				ReflectHelper.setFieldValue(bean, propNames[j], dependBean);
			}
		}

		if (!beansMap.containsKey(beanId)) {
			beansMap.put(beanId, bean);
		}

		return beansMap.get(beanId);
	}
 
	/**
	 * 按ID取得bean
	 * 
	 * @param beanId
	 * @return
	 */
	public Object getBean(String beanId) {
		System.out.println("要取得的:" + beanId);
		return this.beansMap.get(beanId);
	}
 

}


Class_2:辅助解析XML文件的工具类
package com.java.util;

import java.io.File;

import java.util.Iterator;
import java.util.List;

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

/**辅助解析XML文件的工具类
 * @author citizen
 *
 */
public class AnalyzeXMLUtil {

	/**
	 * 获得指定元素的值
	 * 
	 * @param filename
	 *            xml文件的路径
	 * @param elementPath
	 *            元素的xpath路径(例如"/aaa/bbb")
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String[] getElementValue(String filename, String elementPath) {
		try {
			File file = new File(filename);
			SAXReader saxReader = new SAXReader();
			Document doc = saxReader.read(file);

			List<Element> list = doc.selectNodes(elementPath);
			String[] ret = new String[list.size()];
			Iterator<Element> i = list.iterator();
			int count = 0;

			while (i.hasNext()) {
				Element element = i.next();
				ret[count++] = element.getText();
			}

			return ret;
		} catch (Exception e) {
			return new String[0];
		}
	}

	/**
	 * 获得指定元素的值
	 * 
	 * @param filename
	 *            xml文件的路径
	 * @param elementPath
	 *            元素的xpath路径(例如"/aaa/bbb")
	 * @return
	 */
	public static String getSingleElementValue(String filename,
			String elementPath) {
		try {
			File file = new File(filename);
			SAXReader saxReader = new SAXReader();
			Document doc = saxReader.read(file);

			Element element = (Element) doc.selectSingleNode(elementPath);
			return element.getText();
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 * 获得指定属性的值
	 * 
	 * @param filename
	 *            xml文件的路径
	 * @param attributePath
	 *            属性的Xpath路径(例如"//@attr_name")
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static String[] getAttributeValue(String filename,
			String attributePath) {
		try {
			File file = new File(filename);
			SAXReader saxReader = new SAXReader();
			Document doc = saxReader.read(file);

			List<Attribute> list = doc.selectNodes(attributePath);
			String[] ret = new String[list.size()];
			Iterator<Attribute> i = list.iterator();
			int count = 0;

			while (i.hasNext()) {
				Attribute attribute = i.next();
				ret[count++] = attribute.getText();
			}

			return ret;
		} catch (Exception e) {
			return new String[0];
		}
	}

	/**
	 * 获得指定属性的值
	 * 
	 * @param filename
	 *            xml文件的路径
	 * @param attributePath
	 *            属性的Xpath路径(例如"//@attr_name")
	 * @return
	 * @throws Exception
	 */
	public static String getSingleAttributeValue(String filename,
			String attributePath) {
		try {
			File file = new File(filename);
			SAXReader saxReader = new SAXReader();
			Document doc = saxReader.read(file);

			Attribute attribute = (Attribute) doc
					.selectSingleNode(attributePath);

			return attribute.getText();
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 * 获得指定属性的值
	 * 
	 * @param filename
	 *            xml文件的路径
	 * @param elementPath
	 *            属性所在元素的xpath路径(例如"/aaa/bbb")
	 * @param attributeName
	 *            属性的名称
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static String[] getAttributeValue(String filename,
			String elementPath, String attributeName) {
		try {
			File file = new File(filename);
			SAXReader saxReader = new SAXReader();
			Document doc = saxReader.read(file);
	//		System.out.println(elementPath + "[@" + attributeName + "]");
			List<Element> list = doc.selectNodes(elementPath + "[@"
					+ attributeName + "]");
			String[] ret = new String[list.size()];
			Iterator<Element> i = list.iterator();
			int count = 0;

			while (i.hasNext()) {
				Element element = i.next();
				ret[count++] = element.attribute(attributeName).getText();
			}

			return ret;
		} catch (Exception e) {
			return new String[0];
		}
	}

	/**
	 * 获得指定属性的值
	 * 
	 * @param filename
	 *            xml文件的路径
	 * @param elementPath
	 *            属性所在元素的xpath路径(例如"/aaa/bbb")
	 * @param attributeName
	 *            属性的名称
	 * @return
	 * @throws Exception
	 */
	public static String getSingleAttributeValue(String filename,
			String elementPath, String attributeName) {
		try {
			File file = new File(filename);
			SAXReader saxReader = new SAXReader();
			Document doc = saxReader.read(file);

			Element element = (Element) doc.selectSingleNode(elementPath + "[@"
					+ attributeName + "]");
			return element.attribute(attributeName).getText();
		} catch (Exception e) {
			return "";
		}
	}
}


Class_3:容器生成对象时用到的反射类
package com.java.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; 
public class ReflectHelper {
	/**
	 * 获得对象的实例变量值
	 * 
	 * @param owner
	 *            对象实例
	 * @param name
	 *            实例变量的名称
	 * @return 返回实例变量的值
	 */
	public static Object getProperty(Object owner, String name)
			throws Exception {
		Class ownerClass = owner.getClass();
		Field field = ownerClass.getField(name);
		return field.get(owner);
	}

	/**
	 * 获得类的静态变量值
	 * 
	 * @param className
	 *            类的名称(包含包路径)
	 * @param fieldName
	 *            静态变量的名称
	 * @return 返回静态变量的值
	 * @throws Exception
	 */
	public static Object getStaticProperty(String className, String fieldName)
			throws Exception {
		Class classInfo = Class.forName(className);
		Field field = classInfo.getField(fieldName);
		return field.get(null);
	}

	/**
	 * 执行实例对象的方法
	 * 
	 * @param owner
	 *            实例对象
	 * @param methodName
	 *            方法名称
	 * @param args
	 *            方法的参数
	 * @return 返回所执行方法的返回值
	 * @throws Exception
	 */
	public static Object invokeMethod(Object owner, String methodName,
			Object[] args) throws Exception {

		Class ownerClass = owner.getClass();

		Class[] argsClass = new Class[args.length];
		for (int i = 0; i < args.length; i++) {
			argsClass[i] = args[i].getClass();
		}

		Method method = ownerClass.getMethod(methodName, argsClass);

		return method.invoke(owner, args);
	}

	/**
	 * 调用静态方法
	 * 
	 * @param className
	 *            类的名称(包含包路径)
	 * @param methodName
	 *            静态方法的名称
	 * @param args
	 *            方法的参数
	 * @return 执行静态方法的返回值
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Object invokeStaticMethod(String className,
			String methodName, Object[] args) throws Exception {
		Class ownerClass = Class.forName(className);
		Class[] argsClass = new Class[args.length];
		for (int i = 0; i < args.length; i++) {
			argsClass[i] = args[i].getClass();
		}

		Method method = ownerClass.getMethod(methodName, argsClass);
		return method.invoke(null, args);
	}

	/**
	 * 创建一个新实例
	 * 
	 * @param className
	 *            类的名称(包含包路径)
	 * @param args
	 *            构造器的参数
	 * @return 返回新创建的实例对象
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Object newInstance(String className, Object[] args)
			throws Exception {
		Class newObjClass = Class.forName(className);
		if (args != null) {
			Class[] argsClass = new Class[args.length];
			for (int i = 0; i < args.length; i++) {
				argsClass[i] = args[i].getClass();
			}

			Constructor cons = newObjClass.getConstructor(argsClass);

			return cons.newInstance(args);
		} else {
			Constructor cons = newObjClass.getConstructor(null);
			return cons.newInstance(args);
		}
	}

	/**给没有set方法的属性赋值
	 * @param object
	 * @param fieldName
	 * @param value
	 * @throws SecurityException
	 * @throws NoSuchFieldException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public static void setFieldValue(final Object object,final String fieldName,final Object value) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException{
		Field field=object.getClass().getDeclaredField(fieldName);
		field.setAccessible(true);
		field.set(object, value);
	}
	
	
	 

	@SuppressWarnings("unused")
	private static String getMethodNameByFieldName(String fieldName) {
		return "set" + fieldName.substring(0, 1).toUpperCase()
				+ fieldName.substring(1);
	}
}

Class_4:测试类

package test;

import com.java.interfaces.Car;
import com.java.interfaces.Wheel;
import com.java.mySpring.MyIOC;

public class TestMyIOC {
	public static void main(String args[]) throws Exception {
		MyIOC myIOC = new MyIOC();
		Car car1 = (Car) myIOC.getBean("carImpl");
		car1.setColor("green");
		Wheel wheel = (Wheel) myIOC.getBean("wheelImpl");
	 
		System.out.println("对象的信息:"+car1.getId() + " " + car1.getColor() + " "
				+ car1.getWheel().getId() + " " + car1.getWheel().getSize());
		System.out.println("wheel.hashCode()" + wheel.hashCode());
		System.out.println("结束");
	}
}



配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
	<bean id="carImpl" class="com.java.beans.CarImpl">
		<property name="id" value="001" />
		<property name="color" value="red" />
		<property name="wheel" ref="wheelImpl"/>
	</bean>
	<bean id="wheelImpl" class="com.java.beans.WheelImpl">
		<property name="id" value="001" />
		<property name="size" value="50cm" />
	</bean>
</beans>

Interfaces:定义的接口
package com.java.interfaces;

import com.java.beans.WheelImpl;

public interface Car {
	void setId(String id);

	String getId();

	void setColor(String color);

	String getColor();

	void setWheel(WheelImpl wheel);

	WheelImpl getWheel();
}

package com.java.interfaces;

 

public interface Wheel {
	void setId(String id);

	void setSize(String size);
}


Classes:接口对应的实现类

package com.java.beans;

import com.java.interfaces.Car;

public class CarImpl implements Car {
	private String id;
	private String color;
	private WheelImpl wheel;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	public WheelImpl getWheel() {
		return wheel;
	}

	public void setWheel(WheelImpl wheel) {
		this.wheel = wheel;
	}

	 

}


package com.java.beans;

import com.java.interfaces.Wheel;

public class WheelImpl implements Wheel {
	private String id;
	private String size;

	@Override
	public void setId(String id) {
		// TODO Auto-generated method stub
		this.id = id;
	}

	@Override
	public void setSize(String size) {
		// TODO Auto-generated method stub
		this.size = size;
	}

	public String getId() {
		return this.id;
	}

	public String getSize() {
		return this.size;
	}

}

你可能感兴趣的:(java,spring,xml,bean,IOC)