初学Spring,尝试通过java反射机制,解析beans.xml,实现Bean注入。
1、配置文件dom-bean.xml
userDAO
org.jsoft.userDAO.UserDAO
singleton
userService
org.jsoft.service.UserService
prototype
userDAO
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;
}
}
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;
}
}
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;
}
}
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);
}
}
测试结果
单例的
多实例的