欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-03 11:23:36
...
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);
                }
                
            }
    }
    
}
}
}