中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

Java動態代理和反射機制詳解

發布時間:2020-09-24 16:05:21 來源:腳本之家 閱讀:194 作者:MoreThinking 欄目:編程語言

反射機制

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

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

靜態代理

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

動態代理

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

動態代理比靜態代理的優勢在于:

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

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

  1. 在Java的動態代理機制中,有兩個重要的類或接口,一個是InvocationHandler接口,另一個是Proxy類。
  2. InvocationHandler接口是給動態代理類實現的,負責處理被代理對象的操作
  3. Proxy類是用來創建動態代理類實例對象的,只有得到這個對象,才能調用需要代理的方法。
  4. 動態代理的代理類是在靜態代理類上進行修改,將動態代理類實現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動態代理和反射機制詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!

向AI問一下細節

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

AI

名山县| 南雄市| 资阳市| 宁明县| 巴林右旗| 石门县| 延安市| 车致| 红桥区| 涞源县| 阿城市| 榆树市| 托克托县| 齐齐哈尔市| 中超| 金昌市| 通渭县| 宝兴县| 德化县| 印江| 崇明县| 尤溪县| 柳林县| 柞水县| 金溪县| 江口县| 昆山市| 原阳县| 田东县| 阿合奇县| 徐州市| 来宾市| 天峻县| 平阳县| 怀远县| 襄樊市| 武鸣县| 三亚市| 弥勒县| 大竹县| 咸宁市|