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

在学习Spring的过程中,为了更加透彻的理解IOC容器,在讲师的分析下,自我实践了一下IOC的模拟实现:[b]
Class_1:核心的模拟IOC类,其中注释已经十分清晰[/b]
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);
}


}


[b]Class_2:辅助解析XML文件的工具类[/b]

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 "";
}
}
}


[b]Class_3:容器生成对象时用到的反射类[/b]

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);
}
}
[b]
Class_4:测试类[/b]
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);
}

[b]
Classes:接口对应的实现类[/b]

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;
}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值