标签:
本文以一个简单的实例大致模拟Spring IOC/DI的运行原理,代码简单分dao,model,service三层。即:
dao 与数据库的操作,增删改查等方法
model 一般都是javabean对象,例如与数据库的某个表相关联。
service 供外部调用,等于对dao,model等进行了包装。
程序结构图如下:
package com.ctsh.dao; import com.ctsh.model.User; public interface UserDAO { public void save(User user); }
UserDAOImpl.java
package com.ctsh.dao.impl; import com.ctsh.dao.UserDAO; import com.ctsh.model.User; public class UserDAOImpl implements UserDAO { public void save(User user) { System.out.println("user saved!"); } }
User.java
package com.ctsh.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.java
package com.ctsh.service; import com.ctsh.dao.UserDAO; import com.ctsh.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; } }
BeanFactory.java
package com.ctsh.spring; public interface BeanFactory { public Object getBean(String id); }
ClassPathXmlApplicationContext.java
package com.ctsh.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 { 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(); List<Element> list = root.getChildren("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 o = Class.forName(clazz).newInstance(); beans.put(id, o); for (Element propertyElement : (List<Element>) element.getChildren("property")) { String name = propertyElement.getAttributeValue("name"); String bean = propertyElement.getAttributeValue("bean"); Object beanObject = beans.get(bean); String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1); Method m = o.getClass().getMethod(methodName,beanObject.getClass().getInterfaces()[0]); //对对象o(即com.ctsh.service.UserService)调用m方法(即setUserDAO(com.ctsh.dao.UserDAO)方法), //其中传入参数为beanObject(即com.ctsh.dao.impl.UserDAOImpl) m.invoke(o, beanObject); } } } public Object getBean(String id) { return beans.get(id); } }
beans.xml
<beans> <bean id="u" class="com.ctsh.dao.impl.UserDAOImpl" /> <bean id="userService" class="com.ctsh.service.UserService" > <property name="userDAO" bean="u"/> </bean> </beans>
测试类UserServiceTest.java
package com.ctsh.service; import org.junit.Test; import com.ctsh.model.User; import com.ctsh.service.UserService; import com.ctsh.spring.BeanFactory; import com.ctsh.spring.ClassPathXmlApplicationContext; public class UserServiceTest { @Test public void testAdd() throws Exception { BeanFactory applicationContext = new ClassPathXmlApplicationContext(); UserService service = (UserService)applicationContext.getBean("userService"); User u = new User(); u.setUsername("zhangsan"); u.setPassword("123456"); service.add(u); } }
注意上面代码中的ClassPathXmlApplicationContext和BeanFactory均是自己定义的类,并非是Spring中的类。ClassPathXmlApplicationContext实现了BeanFactory接口,程序通过类ClassPathXmlApplicationContext扫描配置文件beans.xml,然后再通过java反射机制装配,将UserDAO注入到类UserService的属性userDAO中。
至于Spring AOP模拟,见博文[Spring系列02]Spring AOP模拟
标签:
原文地址:http://www.cnblogs.com/molyeo/p/4311736.html