目標對象/被代理對象 ------- 房主:真正有租房子方法的人java
代理對象 -------------------- 黑中介:有租房子的方法(負責調用房主的租房子方法)數組
執行代理對象方法的對象 ---- 租房的人 ide
流程:咱們要租房----->中介(租房的方法)------>房主(租房的方法)spa
抽象:調用對象----->代理對象------>目標對象代理
使用代理的好處:能夠在執行目標對象方法的先後執行本身的加工或其它邏輯。相似黑中介在原租房費上要再加錢,原本目標方法返回值房價是1000,黑中介能夠返回值房價+300,就是1300了。code
動態代理:剛剛上圖中的代理對象不須要手動編寫了,不須要一一編寫與目標對象相同的方法,這個過程,在運行時的內存中動態生成代理對象。------字節碼對象級別的代理對象對象
動態代理的API:blog
在jdk的API中存在一個Proxy中存在一個生成動態代理的的方法newProxyInstance接口
|
newProxyInstance |
返回值:Object就是代理對象
參數:loader:表明與目標對象相同的類加載器-------目標對 象.getClass().getClassLoader()
interfaces:表明與目標對象實現的全部的接口字節碼對象數組
h:具體的代理的操做,InvocationHandler接口
注意:JDK的Proxy方式實現的動態代理 目標對象必須有接口 沒有接口不能實現jdk版動態代理
舉個使用的例子:
目標接口:
public interface TargetInterface { public void method1(); public String method2(); public int method3(int x); }
目標對象Target.java:
public class Target implements TargetInterface{ @Override
public void method1() {System.out.println("method1 running...");}@Overridepublic String method2() {System.out.println("method2 running...");return "method2";}@Overridepublic int method3(int x) {return x;}} 使用ProxyTest.java:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import org.junit.Test; public class ProxyTest { @Test public void test1(){ //得到動態的代理對象----在運行時 在內存中動態的爲Target建立一個虛擬的代理對象 //objProxy是代理對象 根據參數肯定究竟是誰的代理對象 TargetInterface objProxy = (TargetInterface) Proxy.newProxyInstance( Target.class.getClassLoader(), //與目標對象相同的類加載器 new Class[]{TargetInterface.class}, //接口 new InvocationHandler() { //invoke 表明的是執行代理對象的方法 @Override //method:表明目標對象的方法字節碼對象 //args:表明目標對象的響應的方法的參數 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("目標方法前的邏輯"); //執行目標對象的方法 Object invoke = method.invoke(new Target(), args); System.out.println("目標方法後的邏輯"); return invoke; } } ); objProxy.method1(); String method2 = objProxy.method2(); System.out.println(method2); } }