JavaEE---------模拟Spring实现IOC
和马士兵老师那里学习来的,希望把自己的见解和大家分享一下
首先我们需要一个总体的概念,这是在做什么?
简单的说,就是把下面这个类似于Spring的beans.xml的xml给解析出来然后作为我们需要的属性值
这也是Ioc的大致概念
先看一下这个xml
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="user" class="com.bq.dao.UserDAOImpl" /> <bean id="userService" class="com.bq.service.UserService"> <property name="userDAO" bean="user" /> </bean> </beans>
比较简单
然后需要相应的实体类,DAO层及其实现,Service类(Hibernate必备知识)
User.java
package com.bq.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; } @Override public String toString() { return "User [username=" + username + ", password=" + password + "]"; } }
UserDAO.java
package com.bq.dao; import com.bq.model.User; public interface UserDAO { public void save(User user); }
UserDAOImpl.java
package com.bq.dao; import com.bq.model.User; public class UserDAOImpl implements UserDAO { @Override public void save(User user) { /* * 在这里我们完成一系列操作 * * Struts 2 的Action调用这里 * Hibernate访问数据库 * others */ System.out.println(user.toString()); System.out.println("user saved!"); } }
UserService.java
package com.bq.service; import com.bq.dao.UserDAO; import com.bq.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; } }
接下来就是如何真正解析xml了,我们用的是jdom库
先创建一个接口以便获得bean
BeanFactory.java
package com.bq.spring; public interface BeanFactory { public Object getBean(String id); }
然后就是核心类ClassPathXmlApplicationContext.java
package com.bq.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; /** * @author 白强 * */ public class ClassPathXmlApplicationContext implements BeanFactory { private Map<String, Object> beans = new HashMap<String, Object>(); // IOC Inverse of Control DI Dependency Injection //直接构造方法中解析beans.xml,具体可参见jdom的使用方法 public ClassPathXmlApplicationContext() throws Exception { SAXBuilder sb = new SAXBuilder(); // 注意如何得到xml Document doc = sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); // 构造文档对象 Element root = doc.getRootElement(); List 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(); System.out.println(id); System.out.println(clazz); //保存在一个HashMap<String, Object>中 beans.put(id, o); //下来分别解析含有property属性值的节点 for (Element propertyElement : (List<Element>) element.getChildren("property")) { String name = propertyElement.getAttributeValue("name"); // userDAO String bean = propertyElement.getAttributeValue("bean"); // user Object beanObject = beans.get(bean);// UserDAOImpl,通过下面这个bean的值可以得到对应的Class String methodName = "set" + name.substring(0, 1).toUpperCase()+ name.substring(1);//用字符串分解合并得到方法名称setUserDAO System.out.println("method name = " + methodName);//打印出methodName Method m = o.getClass().getMethod(methodName,beanObject.getClass().getInterfaces()[0]);//得到具体方法名称 System.out.println(m);//打印出具体的方法名称 m.invoke(o, beanObject);//Java反射注入 } } } public Object getBean(String id) { return beans.get(id); } }
最后来一个测试类测试一下吧,就不用Junit了
Index.java
package com.bq.main; import com.bq.model.User; import com.bq.service.UserService; import com.bq.spring.BeanFactory; import com.bq.spring.ClassPathXmlApplicationContext; /** * @author 白强 * */ public class Index { public static void main(String[] args){ try { BeanFactory applicationContext = new ClassPathXmlApplicationContext(); UserService service = (UserService)applicationContext.getBean("userService"); User u = new User(); u.setUsername("baiqiang"); u.setPassword("Iloveyou"); service.add(u); } catch (Exception e) { e.printStackTrace(); } } }
打印结果如下
user
com.bq.dao.UserDAOImpl
userService
com.bq.service.UserService
method name = setUserDAO
public void com.bq.service.UserService.setUserDAO(com.bq.dao.UserDAO)
User [username=baiqiang, password=Iloveyou]
user saved!
是不是挺有意思的呢?