Java 反射 與 動態(tài)代理

[TOC]

反射

反射

Java是面向?qū)ο笳Z言,Java編譯生成的字節(jié)碼文件應(yīng)該也是一個對象,而這個對象不需要我們定義,

Java已經(jīng)事先定義好了一個類叫做Class

Class類是用來描述現(xiàn)實事物的,是Java語言的最基本單位,類作為一個概念存在,概念本身也是一個對象

而我們使用Class類來描述這個概念類

反射的好處: 通過反射技術(shù)可以獲取到字節(jié)碼文件對象,

使用這個字節(jié)碼文件對象就可以獲取到一個類的所有信息,包括私有

【構(gòu)造方法對象,成員變量對象,成員方法對象,訪問權(quán)限修飾符對象...】

之前的做法:

Student s = new Student();

學(xué)習(xí)反射之后的做法: 可以不需要顯示地出現(xiàn)學(xué)生類就能夠創(chuàng)建學(xué)生類的對象,并且可以動態(tài)創(chuàng)建對象,動態(tài)賦值,動態(tài)調(diào)用方法

相關(guān)對象

Class 類對象

Constructor 構(gòu)造方法對象

Method 成員方法對象

Field 成員變量對象

Modifier 訪問權(quán)限修飾符對象

Array 數(shù)組對象

如何獲取到堆區(qū)中的字節(jié)碼文件對象?

三種方式:

1.通過Object類的getClass方法

缺陷: 必須要顯示創(chuàng)建對象才能夠獲取到對應(yīng)的字節(jié)碼文件對象

2.通過數(shù)據(jù)類型的class屬性

缺點: 必須在代碼中進行硬編碼,當(dāng)生產(chǎn)環(huán)境下切換類的時候需要修改源代碼

優(yōu)點:

1.不需要創(chuàng)建對象

2.當(dāng)一個方法的形參需要我們傳入的是一個Class類型的時候,可以用方式二,很方便

public void method(Class c){}

method(Student.class);

3.通過Class類的一個靜態(tài)方法 Class.forName()

static Class<?> forName(String className)

java.lang.ClassNotFoundException: Student

通過反射獲取構(gòu)造方法對象

Constructor<?>[] getConstructors() 獲取到所有公有修飾的構(gòu)造方法對象數(shù)組

Constructor<?>[] getDeclaredConstructors() 獲取所有構(gòu)造方法對象數(shù)組,包括私有

Constructor<T> getConstructor(Class<?>... parameterTypes) 獲取單個公有修飾構(gòu)造方法對象

Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 獲取所有單個修飾的構(gòu)造方法對象,包括私有

通過反射獲取成員變量對象

Field

Field[] getFields() 獲取所有公有的成員變量對象,包括父類的公有成員

Field[] getDeclaredFields() 獲取所有本類的成員,包括私有

Field getDeclaredField(String name) 獲取公有的成員屬性,包括父類

Field getField(String name) 獲取所有本類屬性,包括私有

通過反射獲取成員方法對象,并且調(diào)用

Method[] getMethods() 獲取所有公有修飾的成員方法對象,包括父類公有方法

Method[] getDeclaredMethods() 獲取本類所有成員方法對象,包括私有方法

Method getMethod(String name, Class<?>... parameterTypes)

Method getDeclaredMethod(String name, Class<?>... parameterTypes)

通過反射讀取配置文件,動態(tài)地調(diào)用任意對象的任意方法

動態(tài)創(chuàng)建對象,動態(tài)調(diào)用方法

  • StudentManager
  • TeacherManager

通過反射獲取數(shù)組對象并且賦值

  • Array

動態(tài)代理

動態(tài)代理

動態(tài)代理的本質(zhì)就是在代理對象方法調(diào)用之前或者之后加入一些通用的方法

面向切面編程就是代理模式的應(yīng)用,也是AOP的基礎(chǔ)

面向切面編程是面向?qū)ο蟮囊环N方式,在代碼的執(zhí)行過程當(dāng)中,動態(tài)嵌入其他代碼,成為面向切面編程

常見的應(yīng)用場景:

1.日志

2.事物

3.數(shù)據(jù)庫操作

面向切面編程的幾個概念:

AOP本質(zhì)就是動態(tài)代理

1.切點(PointCut): 要對哪些連接點進行攔截的定義,即要添加代碼的地方 例如info作為切點

2.連接點(JointPoint): 類里面可以被增強的方法,這些方法稱為連接點 (例如: info run add 三個連接點)

3.增強(通知)(Advice): 指的是攔截到JoinPoint之后所要做的事情就是通知,即向切點插入的代碼片段稱為通知

通知的分類: 前置通知,后置通知,異常通知,最終通知,環(huán)繞通知(后面講解)

4.目標對象(Target): 代理的目標對象,這里就是target

5.織入(Weaving): 是把增強應(yīng)用到目標的過程,即Advice應(yīng)用到Target的過程

6.代理(Proxy): 一個類被AOP織入增強后,就會產(chǎn)生一個結(jié)果代理類

7.引介: 引介是一種特殊的通知在不修改源代碼的前提下,可以在運行時期為類動態(tài)地加入一些方法或者字段

代理模式

代理模式: 23種設(shè)計模式的一種

靜態(tài)代理

動態(tài)代理

通過代理對象,去控制對真實對象的訪問

例如: 經(jīng)紀人, 租房的中介

代理模式的作用: 可以通過代理對象去控制真實對象中的方法,代理對象就可以具備調(diào)用真對象的所有方法的調(diào)用控制權(quán)

我們就可以在調(diào)用方法之前做一些前置處理,之后做一些后置處理

動態(tài)代理:可以在不在修改源代碼的基礎(chǔ)動態(tài)地加入代碼

租房: 1.看安居客app

2.到處走走看看

3.談價錢....

中介來處理

存在真實對象的引用

1.看安居客app

2.到處走走看看

3.談價錢....

4.過來交錢

5.后續(xù)合作

這些方法設(shè)計成為接口

為什么稱為靜態(tài)代理?

這里的代理對象由我們自己來實現(xiàn)的,而JDK中提供了一個類Proxy類能夠動態(tài)地幫助我們創(chuàng)建代理對象或者代理類

Proxy.getProxyClass(loader, interfaces) 動態(tài)獲取代理類

Proxy.newProxyInstance(loader, interfaces, h) 動態(tài)獲取代理對象

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容