1. 程式人生 > >Java的兩種動態代理方式

Java的兩種動態代理方式

 動態代理指被代理者委託代理者完成相應的功能,是攔截器的一種實現方式,其用於攔截類或介面,內部可通過判斷實現對某個方法的攔截。

  jdk方式,委託類必須實現介面,代理類只能對介面進行代理。使用java的反射機制,以及Proxy和InvocationHandler來實現,代理類與委託類實現了相同的介面。 
  cglib,code generate library,代理類可對類進行代理,使用第三方cglib庫來實現,其內部使用asm框架生成代理類的位元組碼,其位元組碼檔案更加複雜,不能代理final方法,因為代理類是委託類的子類。 
  cglib生成的代理類的執行效能比jdk更加優秀,但是生成物件的時間更長,在單例模式中可以使用cglib,在頻繁建立物件的模式中建議使用jdk。隨著jdk版本的提高,jdk的效能會更高,要根據實際情況決定。

// jdk方式
// 被代理介面
public interface Xx() {
    public Integer say(String message);
}

// 委託類
public class XxImpl implements Xx {
    public String say(String name) {
        return "hello " + name;
    }
}

// 攔截器
public class XxInvocationHandler implements InvocationHandler {
    // 委託類
    private Object xxProxyed;

    // 初始化委託類
public void XxInvocationHandler(Object xxProxyed) { this.xxProxyed = xxProxyed; } // proxy,代理類例項,認為是預留介面 // 代理類執行代理方法時,回撥此方法,並將自己this作為實參傳給proxy public Object invoke(Object proxy, Method method, Object[] params) throws Throwable { // 此處可通過method.getName()判斷是否為要攔截的方法
... // 核心方法之前的內容 ... // 以反射的形式,呼叫委託類的方法 Object result = method.invoke(xxProxyed, params); // 核心方法之後的內容 ... // 一定要返回結果 return result; } } // 代理類生成容器 public class ProxyContainer { public static Object createProxy(Object proxyed, InvocationHandler invo) { return Proxy.newProxyInstance(proxyed.getClass().getClassLoader(), proxyed.getClass().getInterfaces(), invo); } } // cglib方式,需要第三方jar庫 // 委託類 public class Yy { public String say(String name) { return "hello " + name; } } // 攔截器 public class YyIntercepter implements MethodInterceptor { // 前三個引數同jdk方式 // methodProxy,委託類中的每一個被代理方法都對應一個MethodProxy物件 public Object intercept(Object proxy, Method method, Object[] params, MethodProxy methodProxy) throws Throwable { // 此處可通過method.getName()判斷是否為要攔截的方法 ... // 核心方法之前的內容 ... // MethodProxy為cgli生成的物件,效能更高也體現在此 Object result = methodProxy.invokeSuper(proxy, params); // 核心方法之後的內容 ... // 一定要返回結果 return result; } } // 代理類生成容器 public class ProxyContainer { public static Object createProxy(Class proxyed) { // cglib自帶的位元組碼增強器 Enhancer enhancer = new Enhancer(); // 將委託類設定成父類 enhancer.setSuperclass(proxyed); // 設定攔截器 enhancer.setCallback(new YyIntercepter()); return enhancer.create(); } }

相關推薦

Java動態代理方式

 動態代理指被代理者委託代理者完成相應的功能,是攔截器的一種實現方式,其用於攔截類或介面,內部可通過判斷實現對某個方法的攔截。  jdk方式,委託類必須實現介面,代理類只能對介面進行代理。使用java的反射機制,以及Proxy和InvocationHandler來實現,代理類

java動態代理

主要分為兩種 jdk代理和cglib開源庫代理   jdk代理主要針對介面,實現InvocationHandler。   cglib主要通過框架修改位元組碼,創建出代理類的子類實現代理, 對於final類不適用. 實現me

vue自定義進度條的製作方法(含css屬性值的動態改變方式

雛形部分接上一篇文章:https://blog.csdn.net/ColourfulTiger/article/details/82910505 結合vue製作自定義的進度條,優勢在於採用了vue特有的樣式繫結,與雙向繫結的方法,達到資料與進度條的進度一致。 突破點:通過變數來動態改變屬性對

基於介面和子類的動態代理的解析及使用

基於介面: package com.itheima.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.P

spring中BeanNameAutoProxyCreator和AnnotationAwareAspectJAutoProxyCreatorAOP代理方式使用總結

昨天程式碼review的過程中,我們遇到了兩種AOP代理的方式,一種是BeanNameAutoProxyCreator,另外一種是AnnotationAwareAspectJAutoProxyCreator。當時大家問這兩種有和區別,十年的老司機 底氣並不足的描述書寫方式不

AOP動態代理的區別

spring 中 AOP是基於 “動態代理” 實現,其採用了兩種方式: java代理:採用java內建的代理API實現 cglib代理:採用第三方API實現 本文主要闡述這兩種方式的區別 動態代理和靜態代理 靜態代理:編譯時將增強程式碼植入class檔案,因為

AOP的動態代理機制

從多處拷貝貼上而來,原文無處可考了,感謝幾位原創者的付出JDK動態代理和Cglib動態代理JDK靜態代理:jdk靜態代理實現比較簡單,一般是直接代理物件直接包裝了被代理物件JDK動態代理:1.能夠繼承靜態代理的全部優點.並且能夠實現程式碼的複用.2.動態代理可以處理一類業務.

MyBatis開發Dao層的方式(Mapper動態代理方式

  MyBatis開發原始Dao層請閱讀我的上一篇部落格:MyBatis開發Dao層的兩種方式(原始Dao層開發)   接上一篇部落格繼續介紹MyBatis開發Dao層的第二種方式:Mapper動態代理方式   Mapper介面開發方法只需要程式設計師編寫Mapper介面(相當於Dao介面),由Mybat

Java動態代理方式

tint lap cto getname AI clas tcl show this JDK中生成代理對象的API 代理類所在包:java.lang.reflect.ProxyJDK實現代理只需要使用newProxyInstance方法,但是該方法需要接收三個參數,完整的

java中線程的創建方式

ring run方法 void div 調用 ext rgs set 線程   第一種:繼承java.lang.Thread類、然後重寫run方法   例如我們模擬一個龜兔賽跑   1 package edu.aeon.thread; 2 3 /** 4 *

Java建立執行緒方式的區別

建立一個執行緒 Java 提供了三種建立執行緒的方法: 通過實現 Runnable 介面; 通過繼承 Thread 類; 通過 Callable 和 Future 建立執行緒。 這裡只介紹兩種第一種和第二種。   1.以建立Runnable介面例項

java POST請求傳參方式JSON格式和表單格式

JSON格式: JSONObject jsonObject = new JSONObject();         jsonObject.put("Action", "action");        &n

Java中BorderLayout佈局管理器的排列實現方式

    java中Frame類預設的佈局管理器為BorderLayout,其主要是將Frame視窗分為東西南北中五個區域,每個區域僅限於放一個元件,如加入多個,前免得會被覆蓋,解決方法為:可以在一個區域中加入文字框Panel,在Panel中可以加入其他的元件。如果不指定加入的

Mybatis進階學習筆記——動態代理方式開發Dao介面、Dao層(推薦第二

1.原始方法開發Dao  Dao介面 1 package cn.sm1234.dao; 2 3 import java.util.List; 4 5 import cn.sm1234.domain.Customer; 6 7 public interface Custo

實現動態代理方式(jdk、cglib、javaassist)

在編寫程式與實現某些功能時,我們經常會使用到動態代理。動態代理是個很簡單但是很有效的東西。在我們平時使用的框架中,像servlet的filter、包括spring提供的aop以及struts2的攔截器都使用了動態代理功能。我們日常看到的mybatis分頁外掛,以及日誌攔截、

單例模式(java方式實現)

//測試類 public class SingletonTest1 { public static void main(String[] args) { //檢驗產生的例項是否是同一個例項 Singleton s

java檔案拷貝方式

一.基礎 三種IO方式 1.傳統IO方式,基於流模型實現,提供了File抽象,輸入輸出流等,互動方式是同步,阻塞的方式,也就是說在讀寫動作完成之前,執行緒一直阻塞在那裡。 2.NIO  引入了Channel,Selector,Buffer等新的抽象,可以構建多路複用的,同步非阻

C語言、Java方式下的——規定範圍內不重複隨機數

示例1:C語言版 #include <stdio.h> #include <stdlib.h> #include <time.h> //隨機產生規定個數的不重複數字 int findSame(int *arr, int in, int

java 方式實現自定義排序

package test; //Comparable 使物件本身具有可比性,這種方式稱為元素的自然順序或預設順序 //Comparator 元素自身不具備比較性或者比較性不是所需要的,在集合初始化讓其具有比較性 (更實用) import java.util.*; //cl

java中Map,遍歷方式

package cn.mdln.study3; import java.util.Map; import java.util.Set; import java.util.Iterator; import java.util.HashMap; /**  * Map,兩種遍歷方