您的位置:首页 > 编程语言 > Java开发

Spring IoC的模拟实现

2012-09-15 12:55 357 查看
Spring最重要的两大块,一个是依赖注入,另一个就是切面编程。其中,依赖注入用的范围更广。在WEB编程之中,通过xml来配置各个Bean之间的关系,使得开发过程更符合高内聚,低耦合的要求。

众所周知,使用Spring时,需要定义一个listener在web.xml文件中。当请求到达服务器是,根据listener,就会自动读取配置的applicationContext.xml文件。这个xml文件中主要配置了各个bean,那么就根据此xml文件,将所需要的bean都自动的生成出来,放在某一个容器中。那么在代码中,调用getBean(beanName)即可以获得所需要的bean,而不需要手动new。非常的方便。

通过对上面过程的理解,我们知道,要实现依赖注入,需要:1.解析xml文件 2.利用反射机制生成bean,并放入容器中,需要时再通过key值来取。第一个,我们可以用jdom来解析xml文件。

假设我们的applicationContext.xml文件的内容如下(纯属模拟,不一定完全一致):

<?xml version="1.0" encoding="utf-8"?>
<beans>
<bean id="userDAO" class="com.SpringLearn.simulate.UserDAO"/>
<bean id="userService" class="com.SpringLearn.simulate.UserService">
<property name="userDAO" ref="userDAO"/>
</bean>
</beans>

可以看到,我们实现的Ioc应该能够产生一个名叫userDAO的com.SpringLearn.simulate.UserDAO的对象,和一个userService对象,且userService对象中的userDAO应该被初始化了,通过setUserDAO设置进去。

那么,既然可以用getBean获取所需的bean对象,那么我们就应该有一个BeanFactory接口。

package com.SpringLearn.simulate;
public interface BeanFactory {

public Object getBean(String beanName);
}

那么有一个ClassPathXmlApplicationContext类实现BeanFactory接口。在其构造函数中,应首先读取xml文件,首先通过bean元素得知对象所属的类和对象的名字,然后再判断其下是否有property标签,如果有,那么获得property标签中ref指定的对象,再通过setxxxx(通过getClass().getMethod()反射实现)将其注入bean对象中。具体的代码如下所示:

package com.SpringLearn.simulate;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
//模拟spring中的一个关键的部分
public class ClassPathXmlApplicationContext implements BeanFactory{

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

//读取配置文件,进行初始化
public ClassPathXmlApplicationContext() {

SAXBuilder saxBuilder = new SAXBuilder();
try {
Document doc = saxBuilder.build("src/com/SpringLearn/simulate/applicationContext.xml");
Element root = doc.getRootElement();
List beans = root.getChildren("bean");
for(int i=0;i<beans.size();i++){

Element elem = (Element)beans.get(i);
String id = elem.getAttributeValue("id");
String beanName = elem.getAttributeValue("class");

Object o = Class.forName(beanName).newInstance();
//读取其下的子元素
List list1 = elem.getChildren("property");
for(int j=0;j<list1.size();j++){

Element elem1 = (Element)list1.get(j);
String name = elem1.getAttributeValue("name");
String ref = elem1.getAttributeValue("ref");

Object property = getBean(ref);
Method method = o.getClass().getMethod("set"+name.substring(0,1).toUpperCase()+name.substring(1),property.getClass());
method.invoke(o,property);
}

//放入map中
map.put(id,o);
}

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public Object getBean(String beanName) {

return map.get(beanName);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring ioc bean object string xml