- 摘要
之前老是聽說動態代理,一直沒有機會好好看過,現在就把動態代理的實現邏輯和用處整理一下。
首先提兩個概念,委託類和代理類。委託類就是實際業務邏輯的處理者,代理類是處於請求發起者與委託類之間的角色,所有對委託類的請求都會經過代理類。
就是委託類將請求處理委託給代理類,代理類可以起到方法攔截、功能增強的作用。
實現動態代理的方式有很多,現在主流的主要jdk和cglib這兩個。下面就用示例程式碼說明下動態代理的過程,以及用動態代理實現攔截器。 - 用JDK實現動態代理
jdk實現動態代理的包是java.lang.reflect.*,jdk實現動態代理有限制,委託類必須要實現介面,所以先要建立一個介面public interface MyInterface { //jdk public void tes1(); //cglib public void test2(String val); }
建立介面實現類
public class MyTarget implements MyInterface { //jdk @Override public void tes1() { System.out.println("委託類業務處理!"); } //cglib @Override public void test2(String val) { System.out.println("業務處理結果:"+val); } }
動態代理邏輯程式碼
package proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class MyProxyTest implements InvocationHandler { //繼承InvocationHandler,攔截方法 private Object target=null; //建構函式 public MyProxyTest(Object target){ this.target = target ; } //獲取代理類的方法 public static Object getProxy(Object target){ //通過proxy建立代理類,需要三個引數,委託類的類載入器、委託類實現的介面、代理類 /** * 這是jdk的動態代理模式,必須要有介面 * proxy會把代理類掛載到所有介面下面 * 如果委託類沒有實現任何介面會有問題,改用CGLIB的enhancer增強類做動態代理 */ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),new MyProxyTest(target)); } //攔截方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("進入代理邏輯!"); System.out.println("代理類處理邏輯!"); Object result=null; result = method.invoke(target,args); System.out.println("委託類處理完後的邏輯!"); return result; } }
getProxy方法就是繫結委託類和代理類之間關係的方法,這裡繫結的代理類是this當前物件,也就是MyProxyTest 的例項物件,由於實現了InvocationHandler介面,所以在方法呼叫之前都會
通過invoke方法,在這裡就可以寫功能增強的程式碼。method.invoke(target,args)是通過反射執行委託類的方法。測試用例
public class JunitTest { public static void main(String[] args) { /** * jdk動態代理 */ System.out.println("---------jdk動態代理--------"); //委託類 MyTarget target = new MyTarget(); //給委託類繫結代理類 MyInterface proxy = (MyInterface)MyProxyTest.getProxy(target); proxy.tes1(); } }
執行結果
---------jdk動態代理-------- 進入代理邏輯! 代理類處理邏輯! 委託類業務處理! 委託類處理完後的邏輯!
我們發現進入了代理類的處理邏輯。
- CGLIB實現動態代理
CGLIB實現動態代理和JDK大同小異,不過CGLIB是通過建立增強類Enhancer,並且設定Enhancer的委託類和代理類來實現動態代理。CGLIB的委託類不需要實現介面。
動態代理邏輯package proxy; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class MyCgLibProxy implements MethodInterceptor { public Object getProxy(Class target){ //建立增強類 Enhancer enhancer = new Enhancer(); //設定委託類 enhancer.setSuperclass(target); //設定代理類 enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("進入代理邏輯!"); System.out.println("代理類處理邏輯!"); Object result=null; result = methodProxy.invokeSuper(o,objects); System.out.println("委託類處理完後的邏輯!"); return result; } }
這裡的getProxy接收的不是委託類的例項物件而是委託類。代理類是this,MyCgLibProxy 的例項物件,由於實現了MethodInterceptor攔截器,所以方法呼叫都會經過intercept。
測試用例
package proxy; public class JunitTest { public static void main(String[] args) { /** * cglib動態代理 */ System.out.println("---------cglib動態代理--------"); MyCgLibProxy cgLib = new MyCgLibProxy(); MyInterface cgLibProxy = (MyInterface)cgLib.getProxy(MyTarget.class); cgLibProxy.test2("cglib動態代理"); } }
執行結果
---------cglib動態代理-------- 進入代理邏輯! 代理類處理邏輯! 業務處理結果:cglib動態代理 委託類處理完後的邏輯!
簡單的實現動態代理的兩種方式就完成了,之後再講解攔截器和責任鏈模式
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
設計模式(一) 動態代理初嘗試
相關文章
- 設計模式:動態代理設計模式
- 設計模式_JAVA動態代理設計模式設計模式Java
- Java設計模式-之代理模式(動態代理)Java設計模式
- 【設計模式】-代理模式及動態代理詳解設計模式
- 23種設計模式之——動態代理模式設計模式
- android常用設計模式之代理設計模式及動態代理原理Android設計模式
- 設計模式總結——代理模式以及java的動態代理設計模式Java
- 設計模式之cglib動態代理設計模式CGLib
- 淺談Java和SAP ABAP的靜態代理和動態代理,以及ABAP面向切面程式設計的嘗試Java程式設計
- Java設計模式學習06——靜態代理與動態代理Java設計模式
- 10分鐘看懂動態代理設計模式設計模式
- 23種設計模式之代理模式(靜態代理)設計模式
- 代理模式 - 動態代理模式
- 面試常問的設計模式之代理模式的詳細解析!分析說明靜態代理模式和動態代理模式面試設計模式
- 【趣味設計模式系列】之【代理模式2--JDK動態代理原始碼解析】設計模式JDK原始碼
- 設計模式學習筆記(七)代理模式以及動態代理的實現設計模式筆記
- Java動態程式設計---動態代理Java程式設計
- 動態代理模式模式
- Java代理設計模式(Proxy)的四種具體實現:靜態代理和動態代理Java設計模式
- 初嘗試swiftSwift
- 【趣味設計模式系列】之【代理模式3--Cglib動態代理原始碼解析】設計模式CGLib原始碼
- 代理模式詳解:靜態代理、JDK動態代理與Cglib動態代理模式JDKCGLib
- 設計模式【3.3】-- CGLIB動態代理原始碼解讀設計模式CGLib原始碼
- 設計模式【3.2】-- JDK動態代理原始碼分析有多香?設計模式JDK原始碼
- 【JAVA】代理模式之Java動態代理Java模式
- 每天一個設計模式·代理模式設計模式
- C#設計模式之代理模式(一)C#設計模式
- 設計模式----代理模式設計模式
- 設計模式——代理模式設計模式
- 設計模式-代理模式設計模式
- 設計模式~代理模式設計模式
- 【設計模式】代理模式設計模式
- 快速迭代業務背景下:設計模式混編的一次嘗試設計模式
- 代理設計模式設計模式
- 《設計模式》之代理模式設計模式
- PHP設計模式-代理模式PHP設計模式
- js設計模式--代理模式JS設計模式
- Java設計模式—代理模式Java設計模式