在第一部分咱們實現讀取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的實現對比。會發現,有不少能夠重構的地方
dom
咱們直接畫一個UML類圖來看吧
測試
代碼實現見:https://github.com/Theone21/mylitespring BeanFactory分支this
本文由博客一文多發平臺 OpenWrite 發佈!3d