Java 反射和動態(tài)代理_第1頁
Java 反射和動態(tài)代理_第2頁
Java 反射和動態(tài)代理_第3頁
Java 反射和動態(tài)代理_第4頁
Java 反射和動態(tài)代理_第5頁
已閱讀5頁,還剩20頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、Java Web分層架構(gòu)類一、 類的生命周期在一個類編譯完成之后,下一步就需要開始使用類,如果要使用一個類,肯定離不開JVM。在程序執(zhí)行中JVM通過裝載,鏈接,初始化這3個步驟完成。1、類的裝載是通過類加載器完成的,加載器將.class文件的二進(jìn)制文件裝入JVM的方法區(qū),并且在堆區(qū)創(chuàng)建描述這個類的java.lang.Class對象。用來封裝數(shù)據(jù)。 但是同一個類只會被類裝載器裝載以前鏈接就是把二進(jìn)制數(shù)據(jù)組裝為可以運行的狀態(tài)。2、鏈接分為校驗,準(zhǔn)備,解析這3個階段a)校驗一般用來確認(rèn)此二進(jìn)制文件是否適合當(dāng)前的JVM(版本);b)準(zhǔn)備就是為靜態(tài)成員分配內(nèi)存空間,并設(shè)置默認(rèn)值。c)解析指的是

2、轉(zhuǎn)換常量池中的代碼作為直接引用的過程,直到所有的符號引用都可以被運行程序使用(建立完整的對應(yīng)關(guān)系)。3、完成之后,類型也就完成了初始化,初始化之后類的對象就可以正常使用了,直到一個對象不再使用之后,將被垃圾回收。釋放空間。當(dāng)沒有任何引用指向Class對象時就會被卸載,結(jié)束類的生命周期。二、類加載器  在java中有三種類類加載器。1)Bootstrap ClassLoader此加載器采用c+編寫,一般開發(fā)中很少見。2)Extension ClassLoader用來進(jìn)行擴(kuò)展類的加載,一般對應(yīng)的是jrelibext目錄中的類3)AppClassLoader加載classpath指定的類,

3、是最常用的加載器。同時也是java中默認(rèn)的加載器。反射一、反射的概念: 主要是指程序可以訪問,檢測和修改它本身狀態(tài)或行為的一種能力,并能根據(jù)自身行為的狀態(tài)和結(jié)果,調(diào)整或修改應(yīng)用所描述行為的狀態(tài)和相關(guān)的語義。通常我們創(chuàng)建一個對象,只需要一句話new,但是new的前提是在知道類名的情況下,如果不知道類名,怎么得到這個類的對象呢?其實我們可以通過反射來實現(xiàn)。一個Java程序在運行時,可以獲得任何一個類的字節(jié)碼信息,包括類的修飾符(public,static等),基類(超類,父類),實現(xiàn)的接口,字段,方法等信息。換句話說,Java程序可以加載一個運行時才得知名稱的class,獲悉其完整構(gòu)造(

4、但不包括methods定義),并逆向生成其對象實體、或?qū)ζ鋐ields設(shè)值、或喚起其methods。  那么java是怎么實現(xiàn)這種機(jī)制的呢?Java的反射機(jī)制是通過反射API來實現(xiàn)的,主要包括以下幾類: 1).Constructor類:用來描述一個類的構(gòu)造方法 2).Field類:用來描述一個類的成員變量 3).Method類:用來描述一個類的方法. 4).Modifer類:用來描述類內(nèi)各元素的修飾符 5).Array:用來對數(shù)組進(jìn)行操作. Constructor,Field,Method這三個類都是JVM(虛擬機(jī))在程序運

5、行時創(chuàng)建的,用來表示加載類中相應(yīng)的成員。也就是說可以通過這些類來獲取和改變反射類的所有成員。反射在框架中是最常用的手段。一個框架是先于調(diào)用者而存在的。當(dāng)程序員用一個框架的時候,你寫的什么類,框架怎么知道,就是通過java反射機(jī)制。Web.xml、Struts2.xml、applicationContext.xml、hibernate.cfg.xml、Peroson.hbm.xml、sqlMapperConfig.xml、PersonMapper.xml等配置文件中的class對應(yīng)的字節(jié)碼,都是通過反射來創(chuàng)建對象的。Param標(biāo)簽中的參數(shù)也是通過反射將其值設(shè)置到對象中。一個標(biāo)準(zhǔn)的javaBean

6、的反射叫做內(nèi)省。mybatis的resultMap標(biāo)簽中,把結(jié)果集的和PO對象的屬性一一對應(yīng)起來,就能把結(jié)果集賦值給PO對象,這也是通過反省實現(xiàn)的。通過mapper.xml中指定的type,得到PO對象。二、反射機(jī)制的作用:1、反編譯:.class->.java2、通過反射機(jī)制訪問java對象的屬性,方法,構(gòu)造方法等;這樣好像更容易理解一些,下邊我們具體看怎么實現(xiàn)這些功能。三、SUN提供的有關(guān)反射機(jī)制中的類java.lang.Class;            

7、0;   java.lang.reflect.Constructor;java.lang.reflect.Field;        java.lang.reflect.Method;java.lang.reflect.Modifier;            很多反射中的方法,屬性等操作我們可以從這四個類中查詢。還是哪句話要學(xué)著不斷的查詢API,那才是我們最好的老師

8、。四、具體功能實現(xiàn)1、反射機(jī)制獲取類有三種方法,我們來獲取Employee類型1. /第一種方式:  2. Classc1 = Class.forName("Employee");  3. /第二種方式:  4. /java中每個類型都有class 屬性.  5. Classc2 = Employee.class;  6.    7. /第三種方式:  8. /java語言中任

9、何一個java對象都有g(shù)etClass 方法  9. Employeee = new Employee();  10. Classc3 = e.getClass(); /c3是運行時類 (e的運行時類是Employee)  2、創(chuàng)建對象:獲取類以后我們來創(chuàng)建它的對象,利用newInstance:1. Class c =Class.forName("Employee");  2.  

10、60;3. /創(chuàng)建此Class 對象所表示的類的一個新實例  4. Objecto = c.newInstance(); /調(diào)用了Employee的無參數(shù)構(gòu)造方法.  3、獲取屬性:分為所有的屬性和指定的屬性:a,先看獲取所有的屬性的寫法: /獲取整個類  1.             Class c = Class.forName("j

11、ava.lang.Integer");  2.               /獲取所有的屬性?  3.             Field fs = c.getDeclaredFields();  4.    

12、    5.               /定義可變長的字符串,用來存儲屬性  6.             StringBuffer sb = new StringBuffer();  7.   &

13、#160;         /通過追加的方法,將每個屬性拼接到此字符串中  8.             /最外邊的public定義  9.             sb.append(Modifier.toString(c.ge

14、tModifiers() + " class " + c.getSimpleName() +"n");  10.             /里邊的每一個屬性  11.             for(Field

15、 field:fs)  12.                 sb.append("t");/空格  13.                 sb.append(Modifier.toString(field

16、.getModifiers()+" ");/獲得屬性的修飾符,例如public,static等等  14.                 sb.append(field.getType().getSimpleName() + " ");/屬性的類型的名字  15.     &#

17、160;           sb.append(field.getName()+"n");/屬性的名字+回車  16.               17.       18.       

18、      sb.append("");  19.       20.             System.out.println(sb);      b,獲取特定的屬性,對比著傳統(tǒng)的方法來學(xué)習(xí):1. public static void 

19、;main(String args) throws Exception  2.               3. <span style="white-space:pre">  </span>/以前的方式:  4.     /* 5.   

20、60; User u = new User(); 6.     u.age = 12; /set 7.     System.out.println(u.age); /get 8.     */  9.            &#

21、160;  10.     /獲取類  11.     Class c = Class.forName("User");  12.     /獲取id屬性  13.     Field idF = c.getDeclaredField("id"); 

22、 14.     /實例化這個類賦給o  15.     Object o = c.newInstance();  16.     /打破封裝  17.     idF.setAccessible(true); /使用反射機(jī)制可以打破封裝性,導(dǎo)致了java對象的屬性不安全。  18.   

23、  /給o對象的id屬性賦值"110"  19.     idF.set(o, "110"); /set  20.     /get  21.     System.out.println(idF.get(o);  22.   4、獲取屬性、方法,和構(gòu)造方法 屬性關(guān)鍵字含義Filed getFiel

24、d(String name)返回一個 Field 對象,它反映此 Class 對象所表示的類或接口的指定公共成員字段。Filed getFiled()返回一個包含某些 Field 對象的數(shù)組,這些對象反映此 Class 對象所表示的類或接口的所有可訪問公共字段。FiledgetDeclaredField(String name)  返回一個 Field 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明字段。FiledgetDeclaredFiled()返回 Field 對象的一個數(shù)組,這些對象反映此 Class 對象所表示的類或接口所聲明的所有字段。方法關(guān)鍵

25、字含義getDeclaredMethods()獲取所有的方法getReturnType()獲得方法的返回類型getParameterTypes()獲得方法的傳入?yún)?shù)類型getDeclaredMethod("方法名",參數(shù)類型.class,)獲得特定的方法構(gòu)造方法關(guān)鍵字含義getDeclaredConstructors()獲取所有的構(gòu)造方法getDeclaredConstructor(參數(shù)類型.class,)獲取特定的構(gòu)造方法父類和父接口含義getSuperclass()獲取某類的父類getInterfaces()獲取某類實現(xiàn)的接口     這樣

26、我們就可以獲得類的各種內(nèi)容,進(jìn)行了反編譯。對于JAVA這種先編譯再運行的語言來說,反射機(jī)制可以使代碼更加靈活,更加容易實現(xiàn)面向?qū)ο?。五、反射加配置文件,使我們的程序更加靈活        在設(shè)計模式學(xué)習(xí)當(dāng)中,學(xué)習(xí)抽象工廠的時候就用到了反射來更加方便的讀取數(shù)據(jù)庫鏈接字符串等,當(dāng)時不是太理解,就照著抄了??匆幌?NET中的反射+配置文件的使用:             當(dāng)時用的配置文件是ap

27、p.config文件,內(nèi)容是XML格式的,里邊填寫鏈接數(shù)據(jù)庫的內(nèi)容:      <configuration>  1. lt;appSettings>  2. <add     key=""  value=""/>  3. lt;/appSettings>  4. </configuration>&#

28、160;  反射的寫法:   1. assembly.load("當(dāng)前程序集的名稱").CreateInstance("當(dāng)前命名空間名稱".要實例化的類名);            這樣的好處是很容易的方便我們變換數(shù)據(jù)庫,例如我們將系統(tǒng)的數(shù)據(jù)庫從SQL Server升級到Oracle,那么我們寫兩份D層,在配置文件的內(nèi)容改一下,或者加條件選擇一下即可,帶來了很大的方便。  &#

29、160;      當(dāng)然了,JAVA中其實也是一樣,只不過這里的配置文件為.properties,稱作屬性文件。通過反射讀取里邊的內(nèi)容。這樣代碼是固定的,但是配置文件的內(nèi)容我們可以改,這樣使我們的代碼靈活了很多!  綜上為,JAVA反射的再次學(xué)習(xí),靈活的運用它,能夠使我們的代碼更加靈活,但是它也有它的缺點,就是運用它會使我們的軟件的性能降低,復(fù)雜度增加,所以還要我們慎重的使用它。六、反射實現(xiàn)動態(tài)調(diào)用方法1、創(chuàng)建UserDao接口2、創(chuàng)建UserDaOracleImpl實現(xiàn)類3、創(chuàng)建UserDaoMySQLImpl實現(xiàn)類4、創(chuàng)

30、建TestUserDao測試類代理模式 代理模式是常用的Java設(shè)計模式,他的特征是代理類與委托類有同樣的接口,代理類主要負(fù)責(zé)為委托類預(yù)處理消息、過濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后處理消息等。代理類與委托類之間通常會存在關(guān)聯(lián)關(guān)系,一個代理類的對象與一個委托類的對象關(guān)聯(lián),代理類的對象本身并不真正實現(xiàn)服務(wù),而是通過調(diào)用委托類的對象的相關(guān)方法,來提供特定的服務(wù)。 按照代理的創(chuàng)建時期,代理類可以分為兩種。 靜態(tài)代理:由程序員創(chuàng)建或特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經(jīng)存在了。 動態(tài)代理:在程序運行時,運用反射機(jī)制動態(tài)

31、創(chuàng)建而成。靜態(tài)代理由程序員創(chuàng)建或工具生成代理類的源碼,再編譯代理類。所謂靜態(tài)也就是在程序運行前就已經(jīng)存在代理類的字節(jié)碼文件,代理類和委托類的關(guān)系在運行前就確定了。靜態(tài)代理的實現(xiàn)步驟1、創(chuàng)建一個UserDao接口2、創(chuàng)建UserDaoMySQLImpl實現(xiàn)類3、創(chuàng)建UserDaoMyOracleImpl實現(xiàn)類4、創(chuàng)建UserService接口5、創(chuàng)建UserService接口的實現(xiàn)類UserServiceImpl6、創(chuàng)建測試類7、執(zhí)行結(jié)果動態(tài)代理Spring主要有兩大思想,一個是IoC,另一個就是AOP,對于IoC,依賴注入就不用多說了,而對于Spring的核心AOP來說,我們不但要知道怎么通過

32、AOP來滿足的我們的功能,我們更需要學(xué)習(xí)的是其底層是怎么樣的一個原理,而AOP的原理就是java的動態(tài)代理機(jī)制。 jdk動態(tài)代理和cglib動態(tài)代理。兩種方法同時存在,各有優(yōu)劣。jdk動態(tài)代理是由Java內(nèi)部的反射機(jī)制來實現(xiàn)的,cglib動態(tài)代理底層則是借助asm來實現(xiàn)的??偟膩碚f,反射機(jī)制在生成類的過程中比較高效,而asm在生成類之后的相關(guān)執(zhí)行過程中比較高效(可以通過將asm生成的類進(jìn)行緩存,這樣解決asm生成類過程低效問題)。還有一點必須注意:jdk動態(tài)代理的應(yīng)用前提,必須是目標(biāo)類基于統(tǒng)一的接口。如果沒有上述前提,jdk動態(tài)代理不能應(yīng)用。由此可以看出,jdk動態(tài)代理有一定的局限性,cglib這種第三方類庫實現(xiàn)的動態(tài)代理應(yīng)用更加廣泛,且在效率上更有優(yōu)勢。一、JDK代理(接口代理)1、JDK代理中的接口和類在java的動態(tài)代理機(jī)制中,有兩個重要的類或接口,一個是 InvocationHandler(Interface)、另一個則是 Proxy(Class),這一個類和接口是實現(xiàn)我們動態(tài)代理所必須用到的。每一個動態(tài)代理類都必須要實現(xiàn)InvocationHandler這個接口,并且每個代理類的實例都關(guān)聯(lián)到了一個handler,當(dāng)我們通過代理對象調(diào)用一個

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論