簡單模擬 spring的bean容器的實現

  原理:從配置文件讀取類的地址,通過Class.forName()方法實例化對象。方法靜態化,使其工廠啓動時,所有的bean以被實例化,可以隨時取。

  思路 :1.定義beanFactory  接口  2.  beanFactoryFactory的實現



定義javabean

public class Hello {
    public void hello(){
        System.out.println("hello spring");
    }
}

寫配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
    xmlns 即 xml namespace xml 使用的命名空間
    xmlns:xsi 即 xml schema instance xml 遵守的具體規範
    xsi:schemaLocation 本文檔 xml 遵守的規範 官方指定
    -->
    <bean id="hello" class="com.shsxt.Hello"/>
</beans>


描述對象屬性的類

public class Entry {
    String name;
    String clazz;
    public Entry(String name,String clazz){
        this.name=name;
        this.clazz=clazz;
    }
}

beanFactory接口定義

public interface BeanFactory {
    Object getBean(String id);
}


beanFactory實現類

public class BeanFactoryImpl implements BeanFactory {
    private static final String BEAN_ID = "id";
    private static final String BEAN_CLASS = "class";
    //對象存放的容器
    private static Map<String,Object> container = new ConcurrentHashMap<String,Object>();
    //從配置文件讀取出來的id和class的鍵值對才存入list
    private static List<Entry> list = new LinkedList<Entry>();
    /**
     * 構造器,傳入配置文件,並初始化bean池
     * @param filePath
     */
    public BeanFactoryImpl(String filePath){
        readXMLHelper(filePath);
        beanInit();
    }

    /**
     * 讀取配置文件,獲取id和class,list
     * @param filePath
     */
    private static void readXMLHelper(String filePath) {
        URL url = BeanFactoryImpl.class.getClassLoader().getResource(filePath);
        SAXReader saxReader = new SAXReader();
        try{
            Document document = saxReader.read(url);
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("sxt","http://www.springframework.org/schema/beans");
            XPath xPath = document.createXPath("//sxt:bean");
            xPath.setNamespaceURIs(map);
            List<Element> elements = xPath.selectNodes(document);
            for (Element element:elements){
                list.add(new Entry(element.attributeValue(BEAN_ID),element.attributeValue(BEAN_CLASS)));
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根據list中的class值,實例化對象,並將對應的id-Object存入容器container內
     */
    private static void beanInit() {
        Iterator<Entry> iterator = list.iterator();
        while(iterator.hasNext()){
            Entry en = iterator.next();
            try{
                Class<?> cls = Class.forName(en.clazz);
                Object obj = cls.newInstance();
                container.put(en.name,obj);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }


    /**
     * 重寫接口的getBean方法,從容器container中取值
     * @param name
     * @return
     */
    public Object getBean(String name) {
        return container.get(name);
    }
}


測試類

public class HelloTest {
    public static void main(String[] args) {
        BeanFactoryImpl ac = new BeanFactoryImpl("spring.xml");
        Object object = ac.getBean("hello");
        Hello hello = (Hello) object;
        hello.hello();
    }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章