1. 程式人生 > >動態代理原理

動態代理原理

eth throwable 自動 結束 ins ati sub 方法 t對象

Spring底層用了哪些技術?(第一 工廠模式 第二 動態代理 ) // 第一個參數是: 類加載器 ClassLoader cl = App.class.getClassLoader(); // 第二個參數:字節碼對象數組 // 第二個參數是字節碼對象數組,表示動態代理創建出來的那個對象,自動實現了哪些接口 Class[] interfaces = new Class[]{ICalculator.class}; // 第三個參數:調用處理器 // 每當調用代理對象的方法時,都不是去執行真正的方法,而是統統進入 調用處理器 對象的invoke方法! // 因為代理對象(所屬的類)已經實現了I接口,所以可以通過代理對象調用I接口中的所有方法: class MyHandler implements InvocationHandler { private Object target; public MyHandler(Object target) { this.target = target; } } ICalculator proxy = (ICalculator) Proxy.newProxyInstance(cl, interfaces, new MyHandler(c)); package com.xaeduask.k_dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Arrays; import org.junit.Test; interface ICalculator { public int add(int a, int b); public int sub(int a, int b); public int mul(int a, int b); public int div(int a, int b); public int mod(int a, int b); } class CalculatorImpl implements ICalculator { public int add(int a, int b) { int r = a + b; return r; } public int sub(int a, int b) { int r = a -b; return r; } public int mul(int a, int b) { int r = a * b; return r; } public int div(int a, int b) { int r = a / b; return r; } public int mod(int a, int b) { int r = a % b; return r; } } class MyHandler implements InvocationHandler { private Object target; public MyHandler(Object target) { this.target = target; } //這裏又有3個參數,一會再解釋 // 第一個參數proxy,就是代理對象本身 // 第二個參數是method,本次正在調用中的代理對象的方法 // 第三個參數是args,表示本次代理對象調用的方法中的參數! public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("aaa"); System.out.println(method.getName()+"開始,參數是:" + Arrays.toString(args)); // 把method代表的方法,當做target對象的方法調用, Object r = method.invoke(target, args); System.out.println(method.getName()+"結束,結果是:" + r); System.out.println("bbb"); return r; // 這裏的返回值,會返回到代理對象調用方法的點用處! } } public class App { @Test public void test() throws Exception { //創建一個目標對象(真實對象,不是代理對象) //調用目標對象的任何方法,都調用的是真正的方法 ICalculator c = new CalculatorImpl(); // 創建代理對象,需要3個參數 // 第一個參數是: 類加載器 // 我們知道,構造器就是用來實例化對象的,其實在構造器的底層實例化對象時,會調用類加載器來實例化對象! // 而使用動態代理也能實例化類的對象,勢必也少不了底層的那個類加載器! ClassLoader cl = App.class.getClassLoader(); // 第二個參數:字節碼對象數組 // 第二個參數是字節碼對象數組,表示動態代理創建出來的那個對象,自動實現了哪些接口 Class[] interfaces = new Class[]{ICalculator.class}; // 第三個參數:調用處理器 // 每當調用代理對象的方法時,都不是去執行真正的方法,而是統統進入 調用處理器 對象的invoke方法! // 因為代理對象(所屬的類)已經實現了I接口,所以可以通過代理對象調用I接口中的所有方法: ICalculator proxy = (ICalculator) Proxy.newProxyInstance(cl, interfaces, new MyHandler(c)); int r = proxy.mod(-5, -2); System.out.println("proxy:" + r); } }

動態代理原理