溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中動態(tài)代理和反射機制的案例分析

發(fā)布時間:2020-10-28 11:51:55 來源:億速云 閱讀:150 作者:小新 欄目:編程語言

這篇文章將為大家詳細講解有關Java中動態(tài)代理和反射機制的案例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

反射機制

Java語言提供的一種基礎功能,通過反射,我們可以操作這個類或?qū)ο?,比如獲取這個類中的方法、屬性和構(gòu)造方法等。

動態(tài)代理:分為JDK動態(tài)代理、cglib動態(tài)代理(spring中的動態(tài)代理)。

靜態(tài)代理

預先(編譯期間)確定了代理者與被代理者之間的關系,也就是說,若代理類在程序運行前就已經(jīng)存在了,這種情況就叫靜態(tài)代理

動態(tài)代理

代理類在程序運行時創(chuàng)建的代理方式。也就是說,代理類并不是在Java代碼中定義的,而是在運行期間根據(jù)我們在Java代碼中的“指示”動態(tài)生成的。

動態(tài)代理比靜態(tài)代理的優(yōu)勢在于:

動態(tài)代理可以很方便的對代理類的函數(shù)進行統(tǒng)一的處理(invoke),而不是修改每個代理類的函數(shù),更靈活和擴展。

JDK的動態(tài)代理(依賴于接口)

在Java的動態(tài)代理機制中,有兩個重要的類或接口,一個是InvocationHandler接口,另一個是Proxy類。

InvocationHandler接口是給動態(tài)代理類實現(xiàn)的,負責處理被代理對象的操作

Proxy類是用來創(chuàng)建動態(tài)代理類實例對象的,只有得到這個對象,才能調(diào)用需要代理的方法。

動態(tài)代理的代理類是在靜態(tài)代理類上進行修改,將動態(tài)代理類實現(xiàn)InvocationHandler接口,重寫Invoke方法,Invoke方法通過傳入的被代理類方法和參數(shù)來執(zhí)行。

如下實例:

public interface AppService {
	void createApp(String name);
	void deleteApp(String name);
}
//代理類(比如微商代理)
public class AppServiceImpl implements AppService{

	@Override
	public void createApp(String name) {
		System.out.print("App["+name+"] has been created.");
	}

	@Override
	public void deleteApp(String name) {
		System.out.print("App["+name+"] has been delete.");
	}
}

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class LoggerInterceptor implements InvocationHandler {
    private Object target; //委托類(被代理類)的實例,比如廠家
    public LoggerInterceptor(Object target){  
        this.target = target;  
    }  
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
		System.out.println("Entered "+target.getClass().getName()+"-"+method.getName()+",with arguments{"+args[0]+"}");  
        Object result = method.invoke(target, args);
       //調(diào)用目標對象的方法  (調(diào)用廠家的方法(createApp)及參數(shù)(Kevin Test))
        System.out.println("Before return:"+result);  
        return result;  
	}

}
import java.lang.reflect.Proxy;

public class test {

public static void main(String[] args) {
    AppService target = new AppServiceImpl();//生成目標對象 (代理類的對象)
    //接下來創(chuàng)建代理對象 
    AppService proxy = (AppService) Proxy.newProxyInstance( 
    target.getClass().getClassLoader(), 
    target.getClass().getInterfaces(), new LoggerInterceptor(target)); 
    proxy.createApp("Kevin Test1"); 
    proxy.deleteApp("Kevin Test2"); 
  }

}/**
* 1、jdk的動態(tài)代理實現(xiàn)方式是依賴于接口的,首先使用接口來定義好操作規(guī)范。
* 2、通過proxy類產(chǎn)生的代理對象調(diào)用被代理對象的操作。
* 3、而這個操作又被分發(fā)給InvocationHandler接口的invoke方法具體執(zhí)行
* 
* 在java的動態(tài)代理機制中,有兩個重要的類或接口,一個是InvocationHandler接口、另一個則是 Proxy類,這個類和接口是實現(xiàn)我們動態(tài)代理所必須用到的。
InvocationHandler接口是給動態(tài)代理類實現(xiàn)的,負責處理被代理對象的操作的,而Proxy是用來創(chuàng)建動態(tài)代理類實例對象的,因為只有得到了這個對象我們才能調(diào)用那些需要代理的方法。
* 
* 此方法的參數(shù)含義如下 
proxy:代表動態(tài)代理對象 
method:代表正在執(zhí)行的方法 
args:代表當前執(zhí)行方法傳入的實參 
返回值:表示當前執(zhí)行方法的返回值
* 
* 如上:
* 使用了Proxy類的newProxyInstance方法生成代理對象,然后用這個對象去調(diào)用createApp()和deleteApp()方法,
* 其實系統(tǒng)會將這2個方法分發(fā)給invoke()方法區(qū)執(zhí)行。其中proxy對象的類是系統(tǒng)幫我們動態(tài)創(chuàng)建了,其實實現(xiàn)了我們的業(yè)務接口AppService
* 
*/

cglib動態(tài)代理(繼承方式)

cglib動態(tài)代理中使用MethodInterceptor來實現(xiàn)動態(tài)代理類。

攔截器MethodInterceptor中就是由MethodProxy的InvokSuper方法調(diào)用代理方法的。

MethodProxy類生成代理方法和代理方法的簽名。

JDK動態(tài)代理和Cglib動態(tài)代理的區(qū)別:

1、JDK動態(tài)代理是實現(xiàn)了被代理對象的接口,Cglib是繼承了被代理對象。

2、Cglib因為是繼承機制,所以無法代理被final修飾的方法。

3、JDK和Cglib都是在運行期間生產(chǎn)字節(jié)碼,JDK是直接寫class字節(jié)碼,Cglib使用ASM框架寫class字節(jié)碼;cglib代理實現(xiàn)更復雜,生成代理類比JDK效率低。

4、JDK調(diào)用代理方法,是通過反射實現(xiàn)機制調(diào)用,cglib是通過Fashclass機制直接調(diào)用方法,效率更高。

Fastcalss機制:

為代理類和被代理類個生成一個class,這個class會為代理類或被代理類的方法分配一個index。

這個index當做一個入?yún)ⅲ現(xiàn)ashclass就可以直接定位要調(diào)用的方法,并直接進行調(diào)用。這樣省去了反射調(diào)用,所以效率高。

關于Java中動態(tài)代理和反射機制的案例分析就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI