实现简单spring的IOC

Spring的IOC让被调用者从调用者中实例化解脱出来。而是通过spring的容器去实现配置文件的解析,以及向容器的注入。
Spring的容器使用了工厂的模式,里面实际是用一个Map存放bean标签的id值和实例化的对象。
下面是一个简单的spring的IOC实例
首先定义model
package com.zhy.spring.framework.bean;

/**
* model
*
* @author Create date
*/
public class JavaBean {
private String name;

private String age;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAge() {
return age;
}

public void setAge(String age) {
this.age = age;
}
}
接下来定义配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="javaBean" class="com.zhy.spring.framework.bean.JavaBean">
       <property name="name">
           <value>James</value>
       </property>
       <property name="age">
           <value>12</value>
       </property>
    </bean>
</beans>
最后定义spring工厂,他完成配置文件的解析,以及IOC的注入
package com.zhy.spring.framework.factory;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

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

import com.zhy.spring.framework.bean.JavaBean;

public class SpringFactory {

/**
* key表示映射文件中bean节点的ID
* value 表示bean对应的对象
*/
private Map<String,Object> factory = new HashMap<String,Object>();

/**
* 解析xml配置文件,ioc对象,最后放入factory中
* @param xmlPath 配置文件的路径
*/
public void init(String xmlPath){
try{
//使用SaxReader进行xml配置文件的读取。
SAXReader saxReader = new SAXReader();
//saxReader的read方法才会返回xml对应的Document,所以需要创建reader对应的InputStream参数

//通过classLoader的getResourceAsStream可以获取对应的InputStream,所以要获取classLoader
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

InputStream in = classLoader.getResourceAsStream(xmlPath);
Document document = saxReader.read(in);
Element root = document.getRootElement();

//遍历root元素下的bean节点,使用element.elementIterator方法
for(Iterator it = root.elementIterator("bean");it.hasNext();){
Element beanEle = (Element)it.next();
//获取ID和class属性
Attribute idAttr = beanEle.attribute("id");
Attribute classAttr = beanEle.attribute("class");

/*
*利用java反射获取class对象
*attribute.getText()后去属性节点对应的值
*beanClass主要的作用就是获取该Class对应的对象的
*/
Class beanClass = Class.forName(classAttr.getText());

//获取beanInfo,beanInfo可以获取该类所具有的属性和方法的相关信息
BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
//获取属性描述
PropertyDescriptor[] pd = beanInfo.getPropertyDescriptors();
//获取实例话对象
Object obj = beanClass.newInstance();

//对bean下的property节点进行遍历
for(Iterator proIte = beanEle.elementIterator("property");proIte.hasNext();){
Element proEle = (Element)proIte.next();
Attribute nameAttri = proEle.attribute("name");

String value=null;
//对property下的value节点进行遍历
for(Iterator valueIte = proEle.elementIterator("value");valueIte.hasNext();){
Element valueEle = (Element)valueIte.next();
value = valueEle.getText();
break;
}
/*
* 将获取的值注入到bean中,利用反射
*  遍历pd数组,找到和name属性节点文本的值相同的项
*  然后将value值注入到对象当中,最后将id和对象存储于map中
*/
for(int i = 0 ; i < pd.length;i++){
PropertyDescriptor descriptor = pd[i];
if(descriptor.getName().equals(nameAttri.getText())){
Method writeMethod = descriptor.getWriteMethod();
writeMethod.invoke(obj,value);
}
}

//将对象放入map中
factory.put(idAttr.getText(),obj);

}
}
}catch(Exception e){
System.out.println(e.getMessage());
}
}

/**
* 根据xml的bean ID获取对应的class实例
* @param beanName
* @return 实例对象
*/
public Object getBean(String beanName){
return factory.get(beanName);
}

public static void main(String[] args) {
//URL url = SpringFactory.class.getResource("/");
String xmlPath = "config.xml";
//System.out.println(xmlPath);

SpringFactory factory = new SpringFactory();
factory.init(xmlPath);
JavaBean  bean = (JavaBean)factory.getBean("javaBean");
//System.out.println(bean.getName());
//System.out.println(bean.getAge());
}
}

猜你喜欢

转载自jameszhao1987.iteye.com/blog/1309704