模拟Spring中applicationContext.xml配置文件初始化bean的过程

时间:2022-01-04 19:39:57
package com.xiaohao.action;

import java.io.File;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * 需要导入dom4j的jar包 
 * @author 小浩
 * @创建日期 2015-4-4
 */
public class BeanFactory {

	
	
	/**
     * 保存容器中所有单例模式的bean实例,这里的hashMap是线程安全的
     *
     */
	
	private static Map<String,Object> beanPool=Collections.synchronizedMap(new HashMap<String,Object>());
    //保存文件对应的Document对象
    private Document document;
    //保存配置文件里的根元素
    private Element root;
    
    /**
     * 构造方法,指定需要读取的文件的路径
     * @param filePath
     * @throws Exception
     */
    public BeanFactory(String filePath) throws Exception{
      
    	//使用dom4j读取xml配置文件
    	SAXReader reader=new SAXReader();
        document=reader.read(new File(filePath));
    	root=document.getRootElement();
    	 //进行容器的初始化
        initPool();
        //初始化单例bean的属性
        initProp();

      }

    
    /**
     * 获取指定的bean
     * @param name
     * @return
     * @throws Exception
     */
	public static Object getBean(String name) throws Exception {
    	Object target = beanPool.get(name);
        //对于单例bean,容器已经初始化了所有的Bean实例
        if(target.getClass() != String.class){
            return target;
        }else{
            String clazz = (String)target;
            //对于非单例的并未注入属性值
            return Class.forName(clazz).newInstance();
        }

	}
    
    
    /**
     * 初始化容器中的所有单例bean
     * */
    private void initPool() throws Exception{
        //遍历配置文件中的每个<bean ../>元素
        for(Object obj:root.elements()){
            Element beanElement = (Element)obj;
            //获取Bean元素中的id属性
            String beanId = beanElement.attributeValue("id");
            //获取bean元素中的class属性
            String beanClazz = beanElement.attributeValue("class"); 
            //获取bean元素中的scope属性
            String beanScope = beanElement.attributeValue("scope"); 
            //如果scope属性不存在或为singleton
            if(beanScope == null|| beanScope.equals("singleton")){
                //以默认构造方法创建bean实例,并将其放入beanPool中
                beanPool.put(beanId, Class.forName(beanClazz).newInstance());   //利用反射的技术
            }else{
                //对于非单例的,存放Bean实现类的类名
               beanPool.put(beanId, beanClazz);
            }
        }
        
    }



/**
 * 初始化容器中的单例bean
 * */
private void initProp() throws Exception{
    //遍历配置文件中的所有bean元素,即根节点的子节点
    for(Object object:root.elements()){
        Element beanElement = (Element)object;
        //获取Bean元素中的id属性
        String beanId = beanElement.attributeValue("id");
        //获取bean元素中的scope属性
        String beanScope = beanElement.attributeValue("scope"); 
        //如果scope属性不存在或为singleton
        if(beanScope == null|| beanScope.equals("singleton")){
            //取出beanPool的指定bean实例
            Object bean = beanPool.get(beanId);
            //遍历bean属性下的所有property属性
            for(Object prop: beanElement.elements()){
                Element probElement = (Element)prop;
                //获取property的name属性
                String propName = probElement.attributeValue("name");
                //获取property的value属性
                String propValue = probElement.attributeValue("value");
                //获取property的ref属性
                String propRef = probElement.attributeValue("ref");
                //将属性名的首字母大写
                String propNameCamelize = propName.substring(0,1).toUpperCase()
                    +propName.substring(1, propName.length());
                //如果value值存在
                if(propValue != null&&propValue.length()> 0){
                    //获取设置注入所需要的setter方法
                    java.lang.reflect.Method setter = bean.getClass().getMethod("set"+propNameCamelize, String.class);
                    //执行setter注入
                    setter.invoke(bean, propValue);
                }
                if(propRef != null&&propRef.length()> 0){
                    //取得需要被注入的bean实例
                    Object target = beanPool.get(propRef);
                    //如果不存在
                    if(target == null){
                        //此处处理单例bean依赖于非单例bean的情形
                    }
                    //定义设值注入需要的setter方法
                    Method setter = null;
                    //遍历target对象所实现的所有方法
                    for(Class superInterface: target.getClass().getInterfaces()){
                        try{
                            //获取设置注入所需要的setter方法
                            setter = bean.getClass().getMethod("set"+propNameCamelize, superInterface);
                            //如果成功获取,跳出循环
                            break;
                        }catch (Exception e) {
                            //如果没有找到就继续下次循环
                            continue;
                        }
                    }
                    //如果setter方法依然是null,直接取得target的实现类对应的setter方法
                    if(setter == null){
                        setter = bean.getClass().getMethod("set"+propNameCamelize, target.getClass());
                    }
                    //执行setter注入
                    setter.invoke(bean, target);
                }
                
            }
    }
    
}
}
}