大四狗閒的沒事,設計實現SPRING 的BEANFACTORY
阿新 • • 發佈:2018-12-29
在一家公司實習,用到了SPRING 框架,感覺自己也能實現這樣的框架,就這麼決定了,一步步滿滿實現它(雖然十有八九會失敗。。)
先試一下實現 BEANFACTORY 吧
首先試著解析這樣的xml檔案
其中 base中有一個屬性為sub,為是d=sub SubBean的引用<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="base" class="com.lee.bean.BaseBean"> <property id="sub" ref="sub" /> </bean> <bean id="sub" class="com.lee.bean.SubBean"/> </beans>
實現的程式碼如下:
OK了 程式碼註釋略少,但是關鍵地方還是有的。package beanfactory; import java.io.File; import java.lang.reflect.Method; 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; import com.lee.bean.BaseBean; import com.lee.bean.SubBean; public class BeanFactory { private static Map<String, Object> map = null; private static SAXReader sax = null; private static Document doc = null; static { init(); } /* * 獲取BEAN */ public static Object getBean(String name) throws Exception { Object obj = map.get(name); if (obj == null) throw new Exception("NO SUCH BEAN"); return obj; } /* * 初始化BEAN工廠 */ public static void init() { try { if (map == null) map = new HashMap<String, Object>(); sax = new SAXReader(); File f = new File(BeanFactory.class.getClassLoader() .getResource("config/config.xml").toURI()); doc = sax.read(f); Element root = doc.getRootElement(); generateBeans(root); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } public static void main(String[] args) throws Exception { SubBean sub = (SubBean) BeanFactory.getBean("sub"); sub.sayHello(); BaseBean base = (BaseBean) BeanFactory.getBean("base"); base.sayHello(); base.getSub().sayHello(); } /* * 解析config.xml 生成BEAN */ private static void generateBeans(Element root) throws Exception { List<?> lst = root.elements(); for (int i = 0; i < lst.size(); i++) { Element e = (Element) lst.get(i); generateBean(e); List<?> list = e.elements(); //處理引用BEAN for (int j = 0; j < list.size(); j++) { Element ee = (Element) list.get(j); String name = ee.attributeValue("id");//得到屬性名稱 String ref = ee.attributeValue("ref");//獲取引用id Object sub = map.get(ref); if (sub == null) { Element se = (Element) (doc .selectSingleNode("beans/bean[@id='" + ref + "']")); sub = generateBean(se); } String clazz = e.attributeValue("class"); Class<?> clz = Class.forName(clazz); Object base = map.get(e.attributeValue("id")); String set = name.substring(0, 1).toUpperCase() + name.substring(1); Method method = clz.getDeclaredMethod("set" + set, new Class[] { sub.getClass() }); method.invoke(base, new Object[] { sub });//反射實現賦值 } } } /* * 生成單個BEAN */ private static Object generateBean(Element e) throws Exception { String name = e.attributeValue("id"); if (map.get(name) != null) return null; String clazz = e.attributeValue("class"); Object obj = Class.forName(clazz).newInstance(); map.put(name, obj); return obj; } }
因為本人沒有什麼工程經驗,所以只是按著自己的理解來實現的,希望大家能夠指出不足。