java反射機制(三)---java的反射和代理實現IOC模式 類比spring
來源:互聯網
上載者:User
IOC(Inverse of Control)可翻譯為“控制反轉”,但大多數人都習慣將它稱為“依賴注入”。在Spring中,通過IOC可以將實作類別、參數資訊等配置在其對應的設定檔中,那麼當需要更改實作類別或參數資訊時,只需要修改設定檔即可,這種方法在上例的基礎上更進一步的降低了類與類之間的耦合。我們還可以對某對象所需要的其它對象進行注入,這種注入都是在設定檔中做的,Spring的IOC的實現原理利用的就是Java的反射機制, Spring還充當了工廠的角色,我們不需要自己建立工廠類。Spring的工廠類會幫我們完成設定檔的讀取、利用反射機制注入對象等工作,我們可以通過bean的名稱擷取對應的對象。 下面讓我們看看如下的類比Spring的bean工廠類: package org.amigo.reflection; import java.io.InputStream; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * bean工廠類. */ public class BeanFactory { private Map<String, Object> beanMap = new HashMap<String, Object>(); /** * bean工廠的初始化. * @param xml xml設定檔 */ public void init(String xml) { try { //讀取指定的設定檔 SAXReader reader = new SAXReader(); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); //從class目錄下擷取指定的xml檔案 InputStream ins = classLoader.getResourceAsStream(xml); Document doc = reader.read(ins); Element root = doc.getRootElement(); Element foo; //遍曆bean for (Iterator i = root.elementIterator("bean"); i.hasNext();) { foo = (Element) i.next(); //擷取bean的屬性id和class Attribute id = foo.attribute("id"); Attribute cls = foo.attribute("class"); //利用Java反射機制,通過class的名稱擷取Class對象 Class bean = Class.forName(cls.getText()); //擷取對應class的資訊 java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean); //擷取其屬性描述 java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors(); //設定值的方法 Method mSet = null; //建立一個對象 Object obj = bean.newInstance(); //遍曆該bean的property屬性 for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) { Element foo2 = (Element) ite.next(); //擷取該property的name屬性 Attribute name = foo2.attribute("name"); String value = null; //擷取該property的子項目value的值 for(Iterator ite1 = foo2.elementIterator("value"); ite1.hasNext();) { Element node = (Element) ite1.next(); value = node.getText(); break; } for (int k = 0; k < pd.length; k++) { if (pd[k].getName().equalsIgnoreCase(name.getText())) { mSet = pd[k].getWriteMethod(); //利用Java的反射極致調用對象的某個set方法,並將值設定進去 mSet.invoke(obj, value); } } } //將對象放入beanMap中,其中key為id值,value為對象 beanMap.put(id.getText(), obj); } } catch (Exception e) { System.out.println(e.toString()); } } /** * 通過bean的id擷取bean的對象. * @param beanName bean的id * @return 返回對應對象 */ public Object getBean(String beanName) { Object obj = beanMap.get(beanName); return obj; } /** * 測試方法.