代码有备注,浅析易懂,别忘了项目中导入jdom.jar
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文件。
<?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>
package com.test.spring;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
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;
/**
* @author 作者 E-mail:ruanjianlxm@sina.com
* @version 创建时间:2015年3月7日 下午7:33:43
* 类说明
*/
public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String, Object> beanMap = new HashMap<String, Object>();
@Override
public Object getBean(String beanName) {
return beanMap.get(beanName);
}
public void ClassPathXmlApplicationContext() throws Exception {
SAXBuilder saxBuilder = new SAXBuilder();
//加载整个文档
Document doc = saxBuilder.build("src/applicationContext.xml");
//加载root
Element rootElement = doc.getRootElement();
//获得所有的bean配置
List beans =rootElement.getChildren("bean");
//轮询所有的bean。挨个获取bean的位置
for (Object object : beans) {
Element elem = (Element)object;
String id = elem.getAttributeValue("id");
Object o = Class.forName(elem.getAttributeValue("class")).newInstance();
List propertylist = elem.getChildren("property");
//轮询bean下的property的配置,对每个依赖进行注入,此处是调用set方法,
//类似于spring3中注入方式的构造方法注入
for (int i = 0; i < propertylist.size(); i++) {
Element e= (Element)propertylist.get(i);
String name = e.getAttributeValue("name");
String ref = e.getAttributeValue("ref");
//获得依赖的bean,准备注入
Object property = getBean(ref);
//调用set方法注入,第一个参数是方法名,第二个参数是执行该方法的具体参数 ,此处property.getClass是指参数是个property配置的对象
Method method =o.getClass().getMethod("set"+name.substring(0,1).toUpperCase()+name.substring(1),property.getClass());
//执行获取的方法,并且传入要执行该方法的的对象O 和要传入的的参数property
method.invoke(o, property);
}
beanMap.put(id, o);//模拟spring上下文,把所有Bean放入map中。需要的时候就从map中获取
}
}
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext c = new ClassPathXmlApplicationContext();
c.ClassPathXmlApplicationContext();
UserService us = (UserService)c.getBean("userService");
us.sayHelloAfterDao();
}
}
----------------------------------------------------------------------------
package com.test.spring;
/**
* @author 作者 E-mail:ruanjianlxm@sina.com
* @version 创建时间:2015年3月7日 下午7:29:13
* 类说明
*/
public class UserService {
UserDAO userDAO ;
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public void sayHelloAfterDao() {
String s= userDAO.say();
System.out.println(s);
}
}
---------------------------------------------------------
package com.test.spring;
/**
* @author 作者 E-mail:ruanjianlxm@sina.com
* @version 创建时间:2015年3月7日 下午7:29:13
* 类说明
*/
public class UserDAO {
public String say(){
String s = "say hello";
return s;
}
}
-----------------------------------------------------
package com.test.spring;
public interface BeanFactory {
public Object getBean(String beanName);
}