解析xml檔案利用反射建立物件並給物件賦值
阿新 • • 發佈:2020-09-12
1、先準備model類,我用lombok了,所以getter和setter方法等自動產生
import lombok.Data; @Data public class Apple implements Fruit{ private String name; private Integer age; private Banana banana; }
import lombok.Data; @Data public class Banana implements Fruit{ private String name; private Integer age; }
2、xml檔案,名字為application.xml
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="apple" class="com.zhiyou.model.Apple"/> <bean id="banana" class="com.zhiyou.model.Banana"/> <bean id="grape" class="com.zhiyou.model.Grape"/> <bean id="mango" class="com.zhiyou.model.Mango"/> <bean id="pear" class="com.zhiyou.model.Pear"/> </beans>
3、建立類來解析xml檔案並給物件賦值
import java.lang.reflect.Field; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader;public class ApplicationContext { // 使用map 來充當IOC容器 private static Map<String, Object> map = new HashMap<String, Object>(); static{ // 獲得一個讀取xml檔案的物件 SAXReader reader = new SAXReader(); try { // 通過reader 獲得xml中所有元素 Document document = reader.read("src/application.xml"); method(document); method2(document); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 用來建立物件 private static void method(Document document) throws Exception{ // 獲取到xml中最外圍的標籤 Element root = document.getRootElement(); // 獲得beans標籤的迭代器,來迭代裡面的bean標籤 Iterator iterator = root.elementIterator(); while(iterator.hasNext()){ // 迴圈獲得bean 標籤 Element bean=(Element) iterator.next(); // 通過class 屬性的value 來建立一個反射物件 Class c = Class.forName(bean.attributeValue("class")); map.put(bean.attributeValue("id"), c.newInstance()); } } // 用來給創建出來的物件注入屬性的 private static void method2(Document document) throws Exception{ // 獲取到xml中最外圍的標籤 Element root = document.getRootElement(); // 獲得beans標籤的迭代器,來迭代裡面的bean標籤 Iterator iterator = root.elementIterator(); while(iterator.hasNext()){ // 迴圈獲得bean 標籤 Element bean=(Element) iterator.next(); // 通過bean 標籤id的value從容器中獲取到物件 Object obj=map.get(bean.attributeValue("id")); // 獲得反射物件 Class c = obj.getClass(); //遍歷bean裡面的property標籤 Iterator iterator2 = bean.elementIterator(); while(iterator2.hasNext()){ Element property = (Element)iterator2.next(); // 通過property標籤中存放的 屬性名稱來建立一個屬性物件 Field field = c.getDeclaredField(property.attributeValue("name")); field.setAccessible(true); if (field.getType().getName().equals("java.lang.Integer")) { field.set(obj, Integer.valueOf(property.getStringValue())); }else if (field.getType().getName().equals("java.lang.String")) { field.set(obj, property.getStringValue()); }else { field.set(obj, map.get(property.attributeValue("ref"))); } } } } public static Object getBean(String name){ return map.get(name); } public static <T>T getBean(Class<T> c){ // 獲得容器中的所有物件集合 Collection<Object> collection = map.values(); // 獲得一個集合的迭代器 Iterator<Object> iterator = collection.iterator(); // 遍歷這個集合 while(iterator.hasNext()){ // 依次取出集合中的物件 Object next = iterator.next(); // 如果集合物件的class 名字 跟傳入的class 名字一致,代表當前的這個物件就是我們要返回的物件 if (next.getClass().getName().equals(c.getName())) { return (T)next; } } return null; } }
getBean()方法利用過載,public static <T>T getBean(Class<T> c)這個方法改進了,之前那個接收的Object,改進的是返回具體的物件
4、測試(測試兩種getBean方法)
public class Test { public static void main(String[] args) { // TODO Auto-generated method stub // Object object = IOC.getBean("apple"); // System.out.println(object); Apple bean = IOC.getBean(Apple.class); System.out.println(bean); } }