Spring是眾多開源 Java 項目中的一員,基於分層的 JavaEE 應用一站式輕量級開源框架,主要核心是IOC控制反轉(Inversion of Control, IoC)和依賴註入(Dependency Injection, DI)這兩大技術。 下麵是一個非常原始,簡易的BeanFactor ...
Spring是眾多開源 Java 項目中的一員,基於分層的 JavaEE 應用一站式輕量級開源框架,主要核心是IOC控制反轉(Inversion of Control, IoC)和依賴註入(Dependency Injection, DI)這兩大技術。
下麵是一個非常原始,簡易的BeanFactory。
通過創建Factory對象調用到構造器,構造器再調用方法,實現自動解析XML配置文件,實例化對象,並完成依賴註入。
1 /** 2 * IOC工廠介面的實現類 3 * 1.在創建實現類對象時解析XML文件 4 * 2.分析解析後的內容,通過反射創建對象,裝入HashMap中 5 * 3.根據傳入的className返回指定對象 6 * 4.依賴註入,給屬性賦值(對象) 7 */ 8 public class Factory02 implements Factory { 9 //用於存放解析xml後得到的bean對象 10 private List<FactoryBeans> beans = new ArrayList<>(); 11 //用於存放完成實例化後的對象 12 private Map<String,Object> map = new HashMap<>(); 13 14 public Factory02(String fileName){ 15 this.parseXml(fileName); 16 this.instanceBean(); 17 this.setBeanProperty(); 18 } 19 20 /** 21 * 為實例化的對象賦值 22 */ 23 private void setBeanProperty() { 24 if(beans.size()>0){ 25 for(FactoryBeans factoryBeans : beans){ 26 //獲取當前bean對象中的property對象集合 27 List<PropertyBean> subElementList = factoryBeans.getPropertyBeanList(); 28 if(subElementList!=null && subElementList.size()>0){ 29 for(PropertyBean propertyBean : subElementList){ 30 //獲取當前property對象中的id 31 String id = propertyBean.getId(); 32 //首字母大寫 用於拼接set方法 33 id = id.toUpperCase().charAt(0)+id.substring(1); 34 //獲取當前property對象中的ref 35 String ref = propertyBean.getRef(); 36 //獲取當前bean對象的類對象 37 Class clazz = map.get(factoryBeans.getId()).getClass(); 38 try { 39 //1.拼接set方法 2.傳入set方法所需要的形參(通過property對象中的ref引用 查找到map中已經生成的對象 40 // 獲取它的Class類對象) 41 Method method = clazz.getDeclaredMethod("set"+id,map.get(ref).getClass()); 42 //執行該set方法 1.指定調用該set方法的類 2.賦的值 即map中已經創建出的指定對象 43 method.invoke(map.get(factoryBeans.getId()),map.get(ref)); 44 } catch (Exception e) { 45 e.printStackTrace(); 46 } 47 } 48 } 49 } 50 } 51 } 52 53 /** 54 * 實例化解析的得到的數據 55 */ 56 private void instanceBean(){ 57 if(beans.size()>0){ 58 try { 59 for(FactoryBeans factoryBeans : beans){ 60 //key為id,value為通過全限定名class實例化得到的對象 61 map.put(factoryBeans.getId(),Class.forName(factoryBeans.getClazz()).newInstance()); 62 } 63 } catch (InstantiationException e) { 64 e.printStackTrace(); 65 } catch (IllegalAccessException e) { 66 e.printStackTrace(); 67 } catch (ClassNotFoundException e) { 68 e.printStackTrace(); 69 } 70 } 71 } 72 73 /** 74 * 解析XML 75 * @param fileName XML文件名 76 */ 77 private void parseXml(String fileName){ 78 //獲取XML的唯一指定資源標識符 79 URL url = this.getClass().getClassLoader().getResource(fileName); 80 if(url!=null){ 81 //創建sax解析對象 82 SAXReader saxReader = new SAXReader(); 83 try { 84 //解析該url指向的文件 85 Document document = saxReader.read(url); 86 //配置xPath需要解析的內容 即所有beans標簽後的bean標簽中的內容 87 XPath xPath = document.createXPath("beans/bean"); 88 //指定解析標簽的範圍為當前整個XML文件(document) 89 List<Element> elementList = xPath.selectNodes(document); 90 if(elementList!=null || elementList.size()>0){ 91 for(Element element : elementList){ 92 //解析property標簽中的內容 93 xPath = document.createXPath("property"); 94 //指定範圍為當前元素下(element) 95 List<Element> subElementList = xPath.selectNodes(element); 96 //創建屬性類對象的集合備用 97 List<PropertyBean> propertyBeanList = null; 98 //通過解析bean標簽得到的id和全限定名 創建factoryBeans對象 99 FactoryBeans factoryBeans = new FactoryBeans(element.attributeValue("id"),element.attributeValue("class")); 100 //判斷當前元素中是否包含屬性property標簽 101 if(subElementList!=null && subElementList.size()>0){ 102 propertyBeanList = new ArrayList<>(); 103 //遍歷該bean標簽中所有的property標簽 創建相對應的property對象 104 for(Element subElement : subElementList){ 105 //裝入集合中 106 //PropertyBean對象中有兩個元素 107 //id:用於創建用來賦值的set方法 除了首字母 其它字元須和被賦值的屬性保持一致 108 //ref:用於引用其它bean標簽 ref必須和被引用的bean標簽id保持一致 109 propertyBeanList.add(new PropertyBean(subElement.attributeValue("id"),subElement 110 .attributeValue("ref"))); 111 } 112 //將property標簽創建的對象裝入factoryBeans的集合屬性中 113 //每個factoryBeans都帶有一個集合屬性 專門用於存放property對象 114 //如果XML中該bean標簽下沒有property標簽 則不會有任何集合產生 115 //反之有多少個property標簽 就會有多少個property對象生成並裝入該集合中 116 factoryBeans.setPropertyBeanList(propertyBeanList); 117 } 118 //將factoryBeans對象裝入集合中 119 beans.add(factoryBeans); 120 } 121 }else{ 122 System.out.println("未解析元素"); 123 } 124 } catch (Exception e) { 125 e.printStackTrace(); 126 } 127 128 }else{ 129 System.out.println("未找到文件"); 130 } 131 } 132 133 /** 134 * IOC工廠介面的實現類方法 135 * @param className 類名 136 * @return 指定類的對象 137 */ 138 @Override 139 public Object getObject(String className) { 140 return map.get(className); 141 } 142 }簡易Spring BeanFactory
初見Spring,如有錯誤的地方,希望對這方面有研究的朋友指出,謝謝!