初学Spring,尝试通过java反射机制,解析beans.xml,实现Bean注入。
1、配置文件dom-bean.xml
<?xml version="1.0" encoding="UTF-8" ?> <html> <beans> <bean> userDAO <class>org.jsoft.userDAO.UserDAO</class> <!--单实例 --> <scope>singleton</scope> </bean> <bean> userService <class>org.jsoft.service.UserService</class> <!--多实例 --> <scope>prototype</scope> <property>userDAO</property> </bean> </beans> </html>
2、DomHandler类解析dom-bean.xml
package org.util.xmlUtil; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * 解析xml * * Map<String,String> beansMap ====>保存一个bean对应的类 * Map<String,List<String>> propertysMap===>保存一个bean对应的属性,需要注入的类 * Map<String,String> scopeMap ===>保存每个bean是scope值 * * @author 北 纬 * */ public class DomHandler { private Map<String,String> beansMap = new HashMap<String,String>(); private Map<String,List<String>> propertysMap = new HashMap<String,List<String>>(); private Map<String,String> scopeMap = new HashMap<String,String>(); public void init(String path) { SAXReader reader = new SAXReader(); Document document= null; try { document = reader.read(new File(path)); } catch (DocumentException e) { // TODO Auto-generated catch block System.out.println("文件未找到!"); e.printStackTrace(); } Element node = document.getRootElement(); listNode(node); } //递归遍历xml所有节点 private void listNode(Element node) { // TODO Auto-generated method stub if("bean".equals(node.getName())){ String key = node.getTextTrim(); Iterator<Element> iterator = node.elementIterator(); while(iterator.hasNext()){ Element element = iterator.next(); if("class".equals(element.getName())){ beansMap.put(key,element.getTextTrim()); }else if("property".equals(element.getName())){ if(propertysMap.containsKey(key)){ propertysMap.get(key).add(element.getTextTrim()); }else{ List<String> strings = new ArrayList<String>(); strings.add(element.getTextTrim()); propertysMap.put(key,strings); } }else if ("scope".equals(element.getName())) { scopeMap.put(key,element.getTextTrim()); } } } Iterator<Element> iterator = node.elementIterator(); while(iterator.hasNext()){ listNode(iterator.next()); } } public Map<String,String> getBeansMap() { return beansMap; } public Map<String,List<String>> getPropertysMap() { return propertysMap; } public Map<String,String> getScopeMap() { return scopeMap; } }
3、IoC容器控制类:ContextControl
package org.util.control; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jsoft.util.str.IocStr; import org.util.xmlUtil.DomHandler; /** * IoC容器控制类 * * @author 北 纬 * */ public class ContextControl { private Map<String,String> beansMap; private Map<String,List<String>> propertysMap; private Map<String,String> scopeMap; // 单例对象表objectMap,存储已经生成过得单例对象 private Map<String,Object> objectMap = new HashMap<String,Object>(); public ContextControl(String path) { // TODO Auto-generated constructor stub DomHandler domHandler = new DomHandler(); domHandler.init(path); beansMap = domHandler.getBeansMap(); propertysMap = domHandler.getPropertysMap(); scopeMap = domHandler.getScopeMap(); // System.out.println("scopeMap里面的内容"); // for(Iterator<Entry<String,String>> iterator = scopeMap.entrySet().iterator();iterator.hasNext(); ){ // Entry<String,String> entry = iterator.next(); // System.out.println(entry.getKey()+":"+entry.getValue()); // } } public Object getBean(String key) { //如果是单例的,并且已经存在 if (objectMap.containsKey(key) && null != objectMap.get(key) && "singleton".equals(scopeMap.get(key))) { return objectMap.get(key); } //创建实例类 Object object = null; try { object = Class.forName(beansMap.get(key)).newInstance(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } //是否有属性需要注入 if (propertysMap.containsKey(key) && null != propertysMap.get(key)) { //获取类的所有属性 Field[] fields = object.getClass().getDeclaredFields(); for (String pKey : propertysMap.get(key)) { for (Field field : fields) { // 比较该属性是否和property值对应bean的class值一样 if (beansMap.get(pKey).equals(field.getType().getName())) { //通过属性名构造对应的set方法 String name = "set" + IocStr.upFirstStr(field.getName()); //System.out.println(name); try { //反射获得该方法 Method method = object.getClass() .getDeclaredMethod(name,getBean(pKey).getClass()); //调用该方法,注入bean method.invoke(object,getBean(pKey)); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } //如果是单例的话,就加入单例对象表objectMap,供下回调用 if ("singleton".equals(scopeMap.get(key))) { objectMap.put(key,object); } return object; } }
4、测试用类
package org.jsoft.userDAO; import org.jsoft.userDAO.userDAOInterf.UserDAOInterf; import org.jsoft.vo.User; public class UserDAO implements UserDAOInterf{ @Override public void add(User user) { System.out.println(user.getName()+" add !" ); } }
</pre><pre name="code" class="java">
package org.jsoft.service; import org.jsoft.service.serviceInterf.UserServiceInterf; import org.jsoft.userDAO.UserDAO; import org.jsoft.vo.User; public class UserService implements UserServiceInterf{ UserDAO dao; @Override public void add(User user) { // TODO Auto-generated method stub dao.add(user); } public UserDAO getDao() { return dao; } public void setDao(UserDAO dao) { this.dao = dao; } }
package test; import org.jsoft.service.UserService; import org.jsoft.userDAO.UserDAO; import org.jsoft.vo.User; import org.util.control.ContextControl; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub ContextControl control = new ContextControl("src/dom-bean.xml"); UserDAO dao = (UserDAO) control.getBean("userDAO"); UserService userService = (UserService) control.getBean("userService"); System.out.println(dao); System.out.println(userService); System.out.println(userService.getDao()); User user = new User(); user.setName("北纬"); userService.add(user); } }
测试结果
单例的
多实例的