日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java反射机制(三)---java的反射和代理实现IOC模式 模拟spring

發(fā)布時間:2025/4/16 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java反射机制(三)---java的反射和代理实现IOC模式 模拟spring 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
IOC(Inverse of Control)可翻譯為“控制反轉(zhuǎn)”,但大多數(shù)人都習(xí)慣將它稱為“依賴注入”。在Spring中,通過IOC可以將實現(xiàn)類、參數(shù)信息等配置在其對應(yīng)的配置文件中,那么當(dāng)需要更改實現(xiàn)類或參數(shù)信息時,只需要修改配置文件即可,這種方法在上例的基礎(chǔ)上更進一步的降低了類與類之間的耦合。我們還可以對某對象所需要的其它對象進行注入,這種注入都是在配置文件中做的,Spring的IOC的實現(xiàn)原理利用的就是Java的反射機制, Spring還充當(dāng)了工廠的角色,我們不需要自己建立工廠類。Spring的工廠類會幫我們完成配置文件的讀取、利用反射機制注入對象等工作,我們可以通過bean的名稱獲取對應(yīng)的對象。 下面讓我們看看如下的模擬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()); ??????????????????????????? ??????????????????????????? //獲取對應(yīng)class的信息 ??????????????????????????? java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean); ??????????????????????????? //獲取其屬性描述 ??????????????????????????? java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors(); ??????????????????????????? //設(shè)置值的方法 ??????????????????????????? Method mSet = null; ??????????????????????????? //創(chuàng)建一個對象 ??????????????????????????? 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的反射極致調(diào)用對象的某個set方法,并將值設(shè)置進去 ???????????????????????????????????????????????? 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?返回對應(yīng)對象 ?????? */ ?????? public Object getBean(String beanName) { ????????????? Object obj = beanMap.get(beanName); ????????????? return obj; ?????? } ?????? ?????? /** ?????? *?測試方法. ?????? * @param args ?????? */ ?????? public static void main(String[] args) { ????????????? BeanFactory factory = new BeanFactory(); ????????????? factory.init("config.xml"); ????????????? JavaBean javaBean = (JavaBean) factory.getBean("javaBean"); ????????????? System.out.println("userName=" + javaBean.getUserName()); ????????????? System.out.println("password=" + javaBean.getPassword()); ?????? } } ???????該類的init(xml)方法,通過指定的xml來給對象注入屬性,為了對該類進行測試,我還需要新建一個JavaBean和在src目錄下新建一個名為config.xml的配置文件。JavaBean的內(nèi)容如下: package org.amigo.reflection; /** * * 簡單的bean,用于測試 ? */ public class JavaBean { ?????? private String userName; ?????? private String password; ?????? ??? public String getPassword() { ????????????? return password; ?????? } ?????? public String getUserName() { ????????????? return userName; ?????? } ?????? public void setUserName(String userName) { ????????????? this.userName = userName; ?????? } ?????? public void setPassword(String password) { ????????????? this.password = password; ?????? } } 這個簡單bean對象中有兩個屬性,分別為userName和password,下面我們在配置文件config.xml中對其屬性注入對應(yīng)的屬性值。配置文件內(nèi)容如下: <?xml?version="1.0"?encoding="UTF-8"?> <beans> ????<bean?id="javaBean"?class="org.amigo.reflection.JavaBean"> ???????<property?name="userName"> ???????????<value>阿蜜果</value> ???????</property> ???????<property?name="password"> ???????????<value>12345678</value> ???????</property> ????</bean> </beans> 類與配置文件都完成后,可以運行BeanFactory.java文件,控制臺顯示內(nèi)容為: userName=阿蜜果 password=12345678 可以看到,雖然在main()方法中沒有對屬性賦值,但屬性值已經(jīng)被注入,在BeanFactory類中的Class bean = Class.forName(cls.getText());通過類名來獲取對應(yīng)的類,mSet.invoke(obj, value);通過invoke方法來調(diào)用特定對象的特定方法,實現(xiàn)的原理都是基于Java的反射機制,在此我們有一次見證了Java反射機制的強大。 當(dāng)然,這只是對IOC的一個簡單演示,在Spring中,情況要復(fù)雜得多,例如,可以一個bean引用另一個bean,還可以有多個配置文件、通過多種方式載入配置文件等等。不過原理還是采用Java的反射機制來實現(xiàn)IOC的。 四.?總結(jié)
在本文中,筆者通過講述Java反射機制概述與初探、IOC使用的背景、IOC粉墨登場等內(nèi)容,演示了Java反射機制API的強大功能,并通過編寫自己的簡單的IOC框架,讓讀者更好的理解了IOC的實現(xiàn)原理。 本文通過IOC的一個簡要實現(xiàn)實例,模擬了Spring中IOC的實現(xiàn),雖然只是完成了Spring中依賴注入的一小部分工作,但是很好的展現(xiàn)了Java反射機制在Spring中的應(yīng)用,能使我們能更好的從原理上了解IOC的實現(xiàn),也能為我們實現(xiàn)自己的準(zhǔn)Spring框架提供

轉(zhuǎn)載于:https://www.cnblogs.com/javaTest/archive/2012/02/23/2589112.html

《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的java反射机制(三)---java的反射和代理实现IOC模式 模拟spring的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。