使用XPath解析xml實現簡單的Spring IOC完成bean的依賴注入
阿新 • • 發佈:2019-02-11
幾天使用Xpath解析xml檔案,例項化bean,完成spring IOC bean的依賴注入的簡單實現。
假設用如下格式的bean檔案:
要完成bean的依賴注入,我們首先需要解析xml檔案,得到結點的class屬性值,然後通過反射呼叫來例項化bean ,將例項bean存入到map<String,Object>中。只是在解析的時候需要有一定的順序:<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="student" class="edu.hue.jk.bean.Student"> <property name="stuName" value="xiao WeiJun"></property> <property name="stuDesc" value="a good student"></property> <property name="pen" ref="redPen"></property> </bean> <bean id="redPen" class="edu.hue.jk.bean.RedPen"> </bean> <bean id="people" class="edu.hue.jk.bean.People"> <property name="peopleName" value="XXX"></property> </bean> </beans>
先初始化沒有property子節點的bean
初始化有property(屬性沒有ref)的bean
初始化有property(有ref)的bean
對應的解析檔案初始化類的程式碼實現:
最後測試程式:package edu.hue.jk.xpath; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; /** * 使用xPath來解析xml 檔案 * 上下文環境,用來解析xml 並作bean的初始化工作 */ public class MyApplicationContext { // 用來存放已經初始化過的bean private Map<String,Object> params; // 配置檔案的路徑 private String filePath; // 建構函式 public MyApplicationContext(String filePath) { super(); this.filePath = filePath; params=new HashMap<String,Object>(); initNoProperty(); initPropertyNoRef(); initPropertyRef(); } // 解析檔案 根據xPath查詢得到結點集合 public NodeList getNodeList(String path){ NodeList result=null; try{ XPathFactory xPathFactory=XPathFactory.newInstance(); XPath xPath=xPathFactory.newXPath(); InputSource inputSource=new InputSource(filePath); result=(NodeList)xPath.evaluate(path, inputSource, XPathConstants.NODESET); } catch(Exception e){ System.out.println(e.getMessage()); } return result; } //getBean方法 public Object getBean(String beanId){ return params.get(beanId); } /**************bean的初始化****************/ // 首先初始化沒有property結點的bean void initNoProperty(){ try{ NodeList list=getNodeList("/beans/bean[not(child::property)]"); for(int i=0;i<list.getLength();i++){ Element element=(Element)list.item(i); //得到bean的Id String beanId=element.getAttribute("id"); //得到bean的class String beanClass=element.getAttribute("class"); //根據反射建立bean的例項 Object obj=Class.forName(beanClass).newInstance(); //存放bean的例項 params.put(beanId, obj); } } catch(Exception e){ System.out.println(e.getMessage()); } } // 然後初始化 有property但是沒有ref屬性的bean void initPropertyNoRef(){ try{ //找到所有沒有 ref屬性的property子節點 並且有property子節點的所有結點 NodeList list=getNodeList("/beans/bean[not(child::property[@ref]) and child::property]"); for(int i=0;i<list.getLength();i++){ Element element=(Element)list.item(i); //得到bean的Id String beanId=element.getAttribute("id"); //得到bean的class String beanClass=element.getAttribute("class"); //根據反射建立bean的例項 Object obj=Class.forName(beanClass).newInstance(); //得到所有的property子節點 NodeList pList=getNodeList("/beans/bean[contains(@id,'"+beanId+"')]"+"/property"); //遍歷子節點,注入屬性 for(int j=0;j<pList.getLength();j++){ //得到property結點 Element pElement=(Element)pList.item(j); //得到屬性的名字 String pName=pElement.getAttribute("name"); //得到屬性的值 String pValue=pElement.getAttribute("value"); //構造方法名 String methodName="set"+(""+pName.charAt(0)).toUpperCase()+pName.substring(1); //根據反射注入屬性 Method method=Class.forName(beanClass).getMethod(methodName,String.class); method.invoke(obj, pValue); } //存放bean的例項 params.put(beanId, obj); } } catch(Exception e){ System.out.println(e.getMessage()); } } //初始化有property子節點且property含有ref屬性的所有bean void initPropertyRef(){ try{ //找到所有有property子節點且property含有ref屬性的所有結點 NodeList list=getNodeList("/beans/bean[child::property[@ref]]"); for(int i=0;i<list.getLength();i++){ Element element=(Element)list.item(i); //得到bean的Id String beanId=element.getAttribute("id"); //得到bean的class String beanClass=element.getAttribute("class"); //根據反射建立bean的例項 Object obj=Class.forName(beanClass).newInstance(); //得到所有的property子節點 NodeList pList=getNodeList("/beans/bean[contains(@id,'"+beanId+"')]"+"/property"); //遍歷子節點,注入屬性 for(int j=0;j<pList.getLength();j++){ //得到property結點 Element pElement=(Element)pList.item(j); //得到屬性的名字 String pName=pElement.getAttribute("name"); //得到屬性的值 String pValue=pElement.getAttribute("value"); //如果屬性依賴於另外的實體 則得到ref屬性 String pref=pElement.getAttribute("ref"); //構造方法名 String methodName="set"+(""+pName.charAt(0)).toUpperCase()+pName.substring(1); //如果屬性值為空,則需要注入依賴屬性 if(pValue==null|| "".equals(pValue)){ Object target=params.get(pref); //System.out.println(target.getClass().getSimpleName()); //根據反射注入屬性 Method method=Class.forName(beanClass).getMethod(methodName,target.getClass()); method.invoke(obj, target); } else{//如果屬性不為空則直接注入屬性 //根據反射注入屬性 Method method=Class.forName(beanClass).getMethod(methodName,String.class); method.invoke(obj, pValue); } } //存放bean的例項 params.put(beanId, obj); } } catch(Exception e){ System.out.println(e.getMessage()); } } }
本程式的附件下載地址:http://download.csdn.net/detail/u010785969/7960093package edu.hue.jk.test; import edu.hue.jk.bean.People; import edu.hue.jk.bean.RedPen; import edu.hue.jk.bean.Student; import edu.hue.jk.xpath.MyApplicationContext; public class Test { public static void main(String[] args) { MyApplicationContext context=new MyApplicationContext("D:\\JavaWeb\\springMvcExercise\\XmlProject\\src\\testBeans.xml"); Student stu=(Student)context.getBean("student"); stu.usePen(); RedPen rpen=(RedPen)context.getBean("redPen"); rpen.showPen(); People people=(People)context.getBean("people"); people.showPeople(); } }