模拟实现Spring IoC功能

为了加深理解Spring 今天自己写了一个模拟的Spring….

步骤:

1.利用jdom解析bean.xml

2.创建ClassPathXmlApplicaitonContext用于模拟IoC

3.先解析所有的<bean/>,再解析所有的<property/>.如果边解析<bean/>,边解析<property/>,会导致property的ref找不到对应的bean.

4.利用简单的反射实现Ioc.

目录结构:

这里只给出核心代码,其余的bean,dao,service,并不重要,就不给出了.有兴趣的同志可以点击~这里下载源码.~

ClassPathXmlApplicationContext:

package glut.spring;import java.io.InputStream;import java.lang.reflect.Method;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Map.Entry;import org.jdom.Document;import org.jdom.Element;import org.jdom.input.SAXBuilder;public class ClassPathXMLApplicationContext {/** * 用于存放<bean/> */private Map<String, Object> beans = new HashMap<>();/** * 用于存放<property/> */private Map<String, List<Element>> properties = new HashMap<>();/** * 将xml文件转为输入流,作为参数传入. * @param is * @throws Exception */public ClassPathXMLApplicationContext(InputStream is) throws Exception {// TODO Auto-generated constructor stubautoWired(is);}/** * 模拟DI * @param is * @throws Exception */private void autoWired(InputStream is) throws Exception {SAXBuilder sb = new SAXBuilder();Document doc = sb.build(is);Element rootElement = doc.getRootElement();List<Element> elementOfBeans = rootElement.getChildren("bean");//遍历xml中所有的<bean/>for (Element e : elementOfBeans) {String beanId = e.getAttributeValue("id");String beanClz = e.getAttributeValue("class");Object beanInstance = Class.forName(beanClz).newInstance();//将beanId和bean的实例存入mapbeans.put(beanId, beanInstance);//把所有的property先存着,等bean初始化完毕再初始化property,否则可能会导致某些property无法初始化properties.put(beanId, e.getChildren("property"));}//Dependency Injection Simulationfor (Entry<String, List<Element>> entry : properties.entrySet()) {for (Element e : entry.getValue()) {String propertyName = e.getAttributeValue("name");String propertyRef = e.getAttributeValue("ref");//通过set方法注入String methodName = "set"+ propertyName.substring(0, 1).toUpperCase()+ propertyName.substring(1);//通过beanId获得对应的beanObject beanInstance = beans.get(entry.getKey());//通过ref的值去寻找对应的bean,如果没有对应的bean,在下面用到getClass的时候会抛出异常.Object refBeanInstance = beans.get(propertyRef);Method setterMethod = beanInstance.getClass().getMethod(methodName,//呵呵,功能有点简陋,默认只支持refBean实现的第一个接口.refBeanInstance.getClass().getInterfaces()[0]);//调用对应的setter方法,将ref的bean注入到指定的bean中.setterMethod.invoke(beanInstance, refBeanInstance);}}}/** * 根据beanName获得bean */public Object getBean(String beanName) {// TODO Auto-generated method stubreturn beans.get(beanName);}}测试代码:package glut.test;import glut.bean.User;import glut.service.UserService;import glut.spring.ClassPathXMLApplicationContext;import org.junit.Test;public class SpringTest {@Testpublic void test() throws Exception {ClassPathXMLApplicationContext ctx = new ClassPathXMLApplicationContext(this.getClass().getClassLoader().getResourceAsStream("beans.xml"));UserService userService = (UserService) ctx.getBean("userService");User user = new User("user", "123");userService.add(user);}}打印的结果为User的toString:

User [uid=user, pwd=123]

版权声明:本文为博主原创文章,,未经博主允许不得转载。

我想有一天和你去旅行。去那没有去过的地方,

模拟实现Spring IoC功能

相关文章:

你感兴趣的文章:

标签云: