首頁 > Java > java教程 > 主體

Java中動態代理和反射機制的詳細介紹(程式碼範例)

不言
發布: 2019-01-24 11:03:13
轉載
5467 人瀏覽過

這篇文章帶給大家的內容是關於Java中動態代理和反射機制的詳細介紹(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

反射機制

Java語言提供的一種基礎功能,透過反射,我們可以操作這個類別或對象,例如取得這個類別中的方法、屬性和構造方法等。

動態代理程式:分為JDK動態代理程式、cglib動態代理程式(spring中的動態代理程式)。

靜態代理程式

預先(編譯期間)決定了代理程式與被代理程式之間的關係,也就是說,若代理類別在程式執行前就已經存在了,這種情況就叫靜態代理

動態代理

代理類別在程式執行時所建立的代理方式。也就是說,代理類別並不是在Java程式碼中定義的,而是在運行期間根據我們在Java程式碼中的「指示」動態產生的。

動態代理程式比靜態代理程式的優勢在於:

動態代理程式可以很方便的對代理類別的函數進行統一的處理(invoke),而不是修改每個代理類別的函數,更靈活和擴展。

JDK的動態代理(依賴介面)

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

InvocationHandler介面是給動態代理類別實現的,負責處理被代理對象的操作

Proxy類別是用來建立動態代理類別實例物件的,只有得到這個對象,才能呼叫需要代理的方法。

動態代理的代理類別是在靜態代理類別上進行修改,將動態代理類別實作InvocationHandler接口,重寫Invoke方法,Invoke方法透過傳入的被代理類別方法和參數來執行。

如下實例:

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);
       //调用目标对象的方法  (调用厂家的方法(createApp)及参数(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();//生成目标对象 (代理类的对象)
    //接下来创建代理对象 
    AppService proxy = (AppService) Proxy.newProxyInstance( 
    target.getClass().getClassLoader(), 
    target.getClass().getInterfaces(), new LoggerInterceptor(target)); 
    proxy.createApp("Kevin Test1"); 
    proxy.deleteApp("Kevin Test2"); 
  }

}/**
* 1、jdk的动态代理实现方式是依赖于接口的,首先使用接口来定义好操作规范。
* 2、通过proxy类产生的代理对象调用被代理对象的操作。
* 3、而这个操作又被分发给InvocationHandler接口的invoke方法具体执行
* 
* 在java的动态代理机制中,有两个重要的类或接口,一个是InvocationHandler接口、另一个则是 Proxy类,这个类和接口是实现我们动态代理所必须用到的。
InvocationHandler接口是给动态代理类实现的,负责处理被代理对象的操作的,而Proxy是用来创建动态代理类实例对象的,因为只有得到了这个对象我们才能调用那些需要代理的方法。
* 
* 此方法的参数含义如下 
proxy:代表动态代理对象 
method:代表正在执行的方法 
args:代表当前执行方法传入的实参 
返回值:表示当前执行方法的返回值
* 
* 如上:
* 使用了Proxy类的newProxyInstance方法生成代理对象,然后用这个对象去调用createApp()和deleteApp()方法,
* 其实系统会将这2个方法分发给invoke()方法区执行。其中proxy对象的类是系统帮我们动态创建了,其实实现了我们的业务接口AppService
* 
*/
登入後複製

cglib動態代理程式(繼承方式)

cglib動態代理程式中使用MethodInterceptor來實作動態代理類。

攔截器MethodInterceptor中就是由MethodProxy的InvokSuper方法呼叫代理方法的。

MethodProxy類別產生代理方法和代理程式方法的簽章。

JDK動態代理程式與Cglib動態代理程式的差異:

#1、JDK動態代理程式是實作了被代理物件的接口,Cglib是繼承了被代理物件。

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

3、JDK和Cglib都是在運行期間生產字節碼,JDK是直接寫class字節碼,Cglib使用ASM框架寫class字節碼;cglib代理實現更複雜,生成代理類比JDK效率低。

4、JDK調用代理方法,是透過反射實現機制調用,cglib是透過Fashclass機制直接調用方法,效率更高。

 Fastcalss機制:

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

這個index當做一個入參,Fashclass就可以直接定位要呼叫的方法,並且直接進行呼叫。這樣省去了反射調用,所以效率高。

以上是Java中動態代理和反射機制的詳細介紹(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:cnblogs.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!