spring的簡易實現(一)

【練習】spring的簡易實現(一)

在第一部分咱們實現讀取xml的配置,而後實例化xml中的bean
首先定義一個xml和相關的class類java

<?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">
  
  <bean id="petStore"
        class="org.litespring.service.v1.PetStoreService" >   
  </bean> 
 <bean id="invalidBean"
        class="xxx.xxxxx" >   
  </bean> 
</beans>
package org.litespring.service.v1;

public class PetStoreService {

}

咱們先把目標寫出來,即測試用例。就是先把咱們想要達到的效果展現出來,而後再一步步的代碼去實現git

package org.litespring.test.v1;

import org.junit.Assert;
import org.junit.Test;
import org.litespring.context.ApplicationContext;
import org.litespring.context.support.ClassPathXmlApplicationContext;
import org.litespring.context.support.FileSystemXmlApplicationContext;
import org.litespring.service.v1.PetStoreService;

public class ApplicationContextTest {

    @Test
    public void testGetBean() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("petstore-v1.xml");
        PetStoreService petStore = (PetStoreService)ctx.getBean("petStore");
        Assert.assertNotNull(petStore);
    }

}

看到這裏,咱們發現本身只要能夠讀取xml(藉助dom4j.jar),以及經過反射實例化一個對象那麼就能夠實現了。按照這個思路,咱們能夠很容易地實現下面這樣的代碼。
首先定義一個BeanDefinition,它用來存儲xml中的bean定義github

public class BeanDefinition {

    private String id;
    private String className;

    public BeanDefinition(String id, String className) {
        this.id = id;
        this.className = className;
    }

    public String getId() {
        return id;
    }

    public String getClassName() {
        return className;
    }
}

而後,咱們實現主體的邏輯部分spring

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

import java.io.InputStream;
import java.util.*;

public class ClassPathXmlApplicationContext {

    private Map<String, BeanDefinition> bds = new HashMap<>();

    public ClassPathXmlApplicationContext(String filePath) throws Exception {
        InputStream is = this.getClass().getClassLoader().getResourceAsStream(filePath);
        SAXReader reader = new SAXReader();
        Document doc = reader.read(is);
        Element root = doc.getRootElement();
        Iterator<Element> iter = root.elementIterator();
        while(iter.hasNext()){
            Element ele = iter.next();
            String id = ele.attributeValue("id");
            String className = ele.attributeValue("class");
            bds.put(id, new BeanDefinition(id, className));
        }
    }

    public Object getBean(String id) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        BeanDefinition bd = bds.get(id);
        String className = bd.getClassName();
        Class<?> clz = this.getClass().getClassLoader().loadClass(className);
        return clz.newInstance();
    }
}

而後,咱們欣喜的看到測試用例能夠成功。最後,咱們反思一下本身寫的代碼,而且和spring的實現對比。會發現,有不少能夠重構的地方
filedom

file

咱們直接畫一個UML類圖來看吧
file測試

代碼實現見:https://github.com/Theone21/mylitespring BeanFactory分支this

本文由博客一文多發平臺 OpenWrite 發佈!3d

相關文章
相關標籤/搜索