上篇中讲解了如何使用BeanFactory加载spring的配置文件,进行bean的实例化。本篇中,自己实现一个BeanFactory来了解其原理。

spring的配置spring-beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans>

    <bean id = "littleBall" class="serviceImpl.LittleBall">
        <property name="girlsName">
            <value>I am little ball!你好,我是小丸子!</value>
        </property>
    </bean>
</beans>

MyBeanFactory:

package beanFactory;

public interface MyBeanFactory {

    public Object getBean(String beanId);

}

MyBeanFacrotyImpl:

package beanFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

/**
 * bean工厂
 * 实例化配置文件中的bean,并提供bean实例的获取方法
 * @author qiaozhong
 */
public class MyBeanFacrotyImpl implements MyBeanFactory{

    //beans中存放所有的bean实例,beans即为Ioc容器
    private static Map<String, Object> beans = new HashMap<String, Object>();

    /**
     * 重写MyBeanFacrotyImpl的构造函数,实例化配置文件中的所有bean,并将其存到beans中
     * @param configLocation
     */
    public MyBeanFacrotyImpl(String configLocation){
        try {
            // 使用jdom的SAXBuilder读取xml文件
            SAXBuilder sb = new SAXBuilder();
            // 加载xml文档进内存
            Document doc = sb.build(this.getClass().getClassLoader()
                    .getResourceAsStream(configLocation));
            // 获取根节点--也就是beans
            Element root = doc.getRootElement();
            // 获取根节点的孩子节点--也就是bean
            @SuppressWarnings("unchecked")
            List<Object> childList = root.getChildren("bean");
            // 循环取出每一个bean节点以及他们的id和class属性,利用反射创建一个对象
            for (int i = 0; i < childList.size(); i++) {
                Element child = (Element) childList.get(i);
                // 获取id属性
                String id = child.getAttributeValue("id");
                // 获取class属性
                String clazz = child.getAttributeValue("class");
                // 通过反射加载类,实例化bean对象
                Object obj = Class.forName(clazz).newInstance();
                // 将实例化的对象放入IOC容器(map)中
                beans.put(id, obj);
            }
        } catch (Exception e) {
            System.out.println("实例化bean出错");
            e.printStackTrace();
        }
    }

    /*
     * 返回beans中的beanId的实例
     * @see beanFactory.MyBeanFactory#getBean(java.lang.String)
     */
    @Override
    public Object getBean(String beanId){
        return beans.get(beanId);
    }
}

TestMyBeanFactory:

package beanFactory;

public class TestMyBeanFactory {

    public static void main(String[] args) {
        MyBeanFactory beanFactory = new MyBeanFacrotyImpl("springConfig/spring-beans.xml");
        System.out.println(beanFactory.getBean("littleBall"));
    }
}
01-01 10:43