模拟spring - 简单实现spring IOC
一、前言
IOC (Inverse of control) - 控制反轉,spring的IOC實現原理為利用Java的反射機制并充當工廠的角色完成對象的裝配和注入。
二、實現細節
附上一張類的結構圖,該例子需要導入jdom.jar和junit.jar
<喎�"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+CqLZINPDu6dCZWFuPC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">package com.zdp.model; // 用戶類 public class User { private String userName; private String password; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }② UserService
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package com.zdp.service; import com.zdp.dao.UserDao; import com.zdp.model.User; public class UserService { ????private UserDao userDao; ????public void add(User user) { ????????userDao.save(user); ????} ????public UserDao getUserDao() { ????????return userDao; ????} ????public void setUserDao(UserDao userDao) { ????????this.userDao = userDao; ????} } |
?
| 1 2 3 4 5 6 7 8 9 10 11 | package com.zdp.dao; import com.zdp.model.User; public class UserDao { ????? ????public void save(User user) { ????????System.out.println("user saved!"); ????} ????? } |
?
| 1 2 3 4 5 6 7 8 | package com.zdp.spring; // Bean工廠接口 public interface BeanFactory { ????? ????public Object getBean(String id); ????? } |
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | package com.zdp.spring; 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.input.SAXBuilder; // Bean工廠實現類 public class ClassPathXmlApplicationContext implements BeanFactory { ????private Map<string, object=""> beans = new HashMap<string, object="">(); ????public ClassPathXmlApplicationContext() throws Exception { ????????SAXBuilder sb = new SAXBuilder(); ????????Document doc = sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); // 構造文檔對象 ????????Element root = doc.getRootElement(); // 獲取根元素HD ????????List list = root.getChildren("bean"); // 取名字為bean的所有元素 ????????for (int i = 0; i < list.size(); i++) { ????????????Element element = (Element) list.get(i); ????????????String id = element.getAttributeValue("id"); ????????????String clazz = element.getAttributeValue("class"); ????????????Object beanObj = Class.forName(clazz).newInstance(); // 反射獲取對象 ????????????beans.put(id, beanObj); // 將對象存入Bean工廠 ????????????for (Element propertyElement : (List<element>) element.getChildren("property")) { ????????????????String name = propertyElement.getAttributeValue("name"); // name="userDao" ????????????????String bean = propertyElement.getAttributeValue("bean"); // bean="userDao" ????????????????Object injectObject = beans.get(bean); // 從Bean工廠中獲取UserDao ????????????????String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1); // setUserDao ????????????????Method method = beanObj.getClass().getMethod(methodName, injectObject.getClass()); ????????????????method.invoke(beanObj, injectObject); // set注入UserDao對象 ????????????} ????????} ????} ????public Object getBean(String id) { ????????return beans.get(id); ????} } </element></string,></string,> |
這里為核心代碼,當然在實際情況中,這一塊要復雜的多, 例如:可以一個bean引用另一個bean,還可以有多個配置文件、通過多種方式載入配置文件等等,不過原理還是采用Java的反射機制。
⑥ 配置文件
?
| 1 2 3 4 5 6 | <beans> ????<bean id="userDao" class="com.zdp.dao.UserDao"> ????<bean id="userService" class="com.zdp.service.UserService"> ????????<property name="userDao" bean="userDao"> ????</property></bean> </bean></beans> |
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package com.zdp.service; import org.junit.Test; import com.zdp.model.User; import com.zdp.spring.BeanFactory; import com.zdp.spring.ClassPathXmlApplicationContext; // 測試代碼 public class UserServiceTest { ????@Test ????public void testAdd() throws Exception { ????????BeanFactory applicationContext = new ClassPathXmlApplicationContext(); // 獲取上下文 ????????UserService service = (UserService) applicationContext.getBean("userService"); // Spring裝配Bean ????????User user = new User(); ????????user.setUserName("zhangsan"); ????????user.setPassword("123456"); ????????service.add(user); // 將user保存入庫 ????} } |
三、小結
上文僅僅是簡單地模擬了spring的IOC的實現,雖然只是完成了spring中依賴注入的一小部分,但還是很好地展現了Java反射機制在spring中的應用,對于初學者理解IOC應該會有一點幫助。
總結
以上是生活随笔為你收集整理的模拟spring - 简单实现spring IOC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring中IoC的入门实例
- 下一篇: 解析Spring IOC原理——工厂模式