练习:通过解析xml和java反射机制实现IoC

初学Spring,尝试通过java反射机制,解析beans.xml,实现Bean注入。

1、配置文件dom-bean.xml



	
		
			userDAO
			org.jsoft.userDAO.UserDAO
			
			singleton
		
		
			userService
			org.jsoft.service.UserService
			
			prototype		
			userDAO
		
	

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 beansMap ====>保存一个bean对应的类
 * Map> propertysMap===>保存一个bean对应的属性,需要注入的类
 * Map scopeMap ===>保存每个bean是scope值
 * 
 * @author 北 纬
 *
 */
public class DomHandler {
	private Map beansMap = new HashMap();
	private Map> propertysMap = new HashMap>();
	private Map scopeMap =  new HashMap();
	
	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 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 strings = new ArrayList();
						strings.add(element.getTextTrim());
						propertysMap.put(key, strings);
					}
				}else if ("scope".equals(element.getName())) {
					scopeMap.put(key, element.getTextTrim());
				}
			}
		}
		
		Iterator iterator = node.elementIterator();
		while(iterator.hasNext()){
			listNode(iterator.next());
		}

	}
	
	public Map getBeansMap() {
		return beansMap;
	}
	public Map> getPropertysMap() {
		return propertysMap;
	}

	public Map 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 beansMap;
	private Map> propertysMap;
	private Map scopeMap;

	// 单例对象表objectMap,存储已经生成过得单例对象
	private Map objectMap = new HashMap();

	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> iterator = scopeMap.entrySet().iterator();iterator.hasNext(); ){
//			Entry  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 !" );
	}
}
 
  
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;
	}
	

}


5、测试代码

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);
		

	}

}



测试结果

单例的

练习:通过解析xml和java反射机制实现IoC_第1张图片

多实例的

练习:通过解析xml和java反射机制实现IoC_第2张图片


你可能感兴趣的:(学习之路)