模擬Spring的屬性裝配

尊重原創。。謝謝你們

思想:
  1:正常加載全部類。若是發現有prop引用,則去cache(map)中去查詢這個bean是否存在若是不存在則再去讀取xml中的配置實例化這個信息。
  2:能夠使用遞歸實現。



package cn.core;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class MyApplication {
   private Map<String, Object> cache = new HashMap<String, Object>();
   public MyApplication(String config) {
   try {
   //獲得真實路徑
   URL url = MyApplication.class.getClassLoader().getResource(config);
   File file = new File(url.getPath());
   SAXReader sax = new SAXReader();
   Document dom = sax.read(file);
   parseXml(dom, "//bean");
  } catch (Exception e) {
   throw new RuntimeException(e);
  }
 }
 // 開發一個方法用於解析xml文件
 // 接收兩個參數第一個參數,是dom,第二個參數是查詢哪些元素
 public void parseXml(Document dom, String xpath) throws Exception {
  List<Element> list = dom.selectNodes(xpath);
  for (Element e : list) {
   String id = e.attributeValue("id");
   if (cache.containsKey(id)) {//若是在緩存中已經包含了這個id
    continue;
   }
   String cls = e.attributeValue("cls");
   Object obj = Class.forName(cls).newInstance();
   cache.put(id, obj);
   List<Element> props = e.elements();
   for (Element p : props) {
    String name = p.attributeValue("name");//
    Object val = p.attributeValue("value");// 1:先讀取value這個屬性
    if (val == null) {// 2:若是沒有value這個屬性,則就去讀取ref這個屬性
     val = p.attributeValue("ref");
     if (val != null) {
      if (!cache.containsKey(val)) {// 這個bean尚未實例化呢//
       // 直接根據id先去加載這個類
       String xpath2 = "//bean[@id='" + val + "']";
       parseXml(dom, xpath2);
      }
      val = cache.get(val);// 上面解析完成之後,在cache緩存中必定是存在這個id元素的
     }
    }
    PropertyDescriptor pd = new PropertyDescriptor(name,
      obj.getClass());
    if (pd.getPropertyType() == Integer.class
      || pd.getPropertyType() == int.class) {
     pd.getWriteMethod().invoke(obj, Integer.parseInt("" + val));
    } else {
     pd.getWriteMethod().invoke(obj, val);
    }
   }
  }
 }
 public <T> T getBean(String id, Class<T> class1) {
  Object obj = cache.get(id);// 根據id從map中獲取值
  return (T) obj;
 }
}
實體類
package cn.demo;
import org.junit.Test;
import cn.core.MyApplication;
import cn.domain.Person;
public class Demo01 {
 @Test
 public void test1() {
  MyApplication app = new MyApplication("cn/demo/mybeans.xml");
  Person p1 = app.getBean("person",Person.class);
  System.err.println(p1);
 }
}
自定義配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
 <bean id="aa" cls="cn.domain.Address">
  <prop name="zip" value="10085" />
  <prop name="tel" value="198393843" />
 </bean>
 <bean id="person" cls="cn.domain.Person">
  <prop name="name" value="Jack" />
  <prop name="age" value="33" />
  <prop name="addr" ref="aa"/>
 </bean>
</beans>
相關文章
相關標籤/搜索