Spring笔记(第一弹:简单模拟Spring IOC)
2015-08-30 19:54
453 查看
Spring博大精深,功能非常多。我们这里简单的模拟一下spring的IOC。
先把model,dao,service写出来,写一个最简单的为例。
在model包下定义一个User:
在dao包下定义一个UserDAO:
在dao.impl包下定义一个UserDAOImpl:
在service包下定义一个UserService:
在service.impl包下定义一个UserServiceImpl:
注意这个UserServiceImpl里的userDAO属性要提供好get,set方法,因为我们后面要通过反射机制,把dao给set进来。
下面就是重头戏了,我们要模拟spring,自然要写一个ApplicationContext.xml:
再模拟一个BeanFactory:
再来一个ClassPathXmlApplicationContext,实现BeanFactory接口:
以上已经模拟完成,我们测试一下:
运行一下,可以看到控制台输出:
到此,我们已经成功的模拟了一个最简单的spring。
先把model,dao,service写出来,写一个最简单的为例。
在model包下定义一个User:
package com.hello.model; public class User { private String userId; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } private String userName; }
在dao包下定义一个UserDAO:
package com.hello.dao; import com.hello.model.User; public interface UserDAO { public void add(User user); }
在dao.impl包下定义一个UserDAOImpl:
package com.hello.dao.impl; import com.hello.dao.UserDAO; import com.hello.model.User; public class UserDAOImpl implements UserDAO { @Override public void add(User user) { System.out.println("A user added!"); } }
在service包下定义一个UserService:
package com.hello.service; import com.hello.model.User; public interface UserService { public void add(User user); }
在service.impl包下定义一个UserServiceImpl:
package com.hello.service.impl; import com.hello.dao.UserDAO; import com.hello.model.User; import com.hello.service.UserService; public class UserServiceImpl implements UserService { private UserDAO userDAO; public UserDAO getUserDAO() { return userDAO; } public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; } @Override public void add(User user) { userDAO.add(user); } }
注意这个UserServiceImpl里的userDAO属性要提供好get,set方法,因为我们后面要通过反射机制,把dao给set进来。
下面就是重头戏了,我们要模拟spring,自然要写一个ApplicationContext.xml:
<beans> <bean id="userDAOImpl" class="com.hello.dao.impl.UserDAOImpl" /> <bean id="userServiceImpl" class="com.hello.service.impl.UserServiceImpl"> <property name="userDAO" ref="userDAOImpl"></property> </bean> </beans>
再模拟一个BeanFactory:
package com.hello.spring; public interface BeanFactory { public Object getBean(String name); }
再来一个ClassPathXmlApplicationContext,实现BeanFactory接口:
package com.hello.spring; import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.input.SAXBuilder; public class ClassPathXmlApplicationContext implements BeanFactory { // 从配置文件里解析出来的所有的bean都会放在这个容器里 private Map<String, Object> beans = new HashMap<String, Object>(); public ClassPathXmlApplicationContext() throws Exception { SAXBuilder sb = new SAXBuilder(); // 读取配置文件 Document document = sb.build(this.getClass().getClassLoader().getResourceAsStream("ApplicationContext.xml")); // 获取跟节点,即beans节点 Element rootElement = document.getRootElement(); // 获取所有的bean节点 List<Element> elementList = rootElement.getChildren("bean"); // 遍历每一个bean节点,把所有的bean都放到beans容器中,并对每一个bean进行自动装配 for (int i = 0; i < elementList.size(); i++) { // 读取bean节点的id和class属性 Element element = elementList.get(i); String id = element.getAttributeValue("id"); String clazz = element.getAttributeValue("class"); // 通过反射获取这个class对应的实例 Object o = Class.forName(clazz).newInstance(); // 放入到beans容器中 beans.put(id, o); // 遍历这个bean中所有的property节点 for (Element propertyElement : element.getChildren("property")) { // 读取property节点的name属性,这个name就是要注射的bean的名字 String name = propertyElement.getAttributeValue("name"); // 读取property节点的ref属性,这个ref就是在beans容器中的bean的名字 String ref = propertyElement.getAttributeValue("ref"); // 从beans容器中获取到这个ref所对应的bean Object refBeanObject = beans.get(ref); // 根据name,构造出set方法的方法名 String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1); // 根据方法名和参数获取到set方法 Method m = o.getClass().getMethod(methodName, refBeanObject.getClass().getInterfaces()[0]); // 调用set方法,进行注射。这样就实现了自动装配 m.invoke(o, refBeanObject); } } } @Override public Object getBean(String name) { return beans.get(name); } }
以上已经模拟完成,我们测试一下:
package com.hello.spring; import com.hello.model.User; import com.hello.service.UserService; public class test { public static void main(String[] args) throws Exception { BeanFactory beanFactory = new ClassPathXmlApplicationContext(); UserService userService = (UserService) beanFactory.getBean("userServiceImpl"); userService.add(new User()); } }
运行一下,可以看到控制台输出:
A user added!
到此,我们已经成功的模拟了一个最简单的spring。
相关文章推荐
- Java中泛型数组的实现
- SpringMVC Helloword
- java web技术搜索知多少(更新中)
- JavaEE程序编码规范
- Debug JDK source 无法查看局部变量的问题解决方案
- java并发编程实战第六章(1)并发集合介绍
- 开启java生活
- Java发送短信
- 适配器模式
- struts2之Action 4000 名称的搜索顺序
- 装饰者模式
- java RTTI笔记整理
- JAVA问题总结之19--方法的重载(overload)
- 实训第一周java小练习
- Java学习之路:不走弯路,就是捷径
- 如何实现自己的输入流
- 没有指针的Java语言
- 深度学习:Java 自动装箱和拆箱(好文)
- Java Socket(3): NIO
- Eclipse编译ImageJ