【Java基礎】【動態代理 一個動態代理的例子】
阿新 • • 發佈:2019-02-04
參考資料:
阿里雲大學MLDN高階開發課程
2016黑馬程式設計師JAVAEE Day25 基礎加強
動態代理是理解Spring AOP功能的一個重要概念
程式碼例子:
動態代理用於介面TargetInterface
實體類Target和代理類ProxyTest都實現了TargetInterface
1. TargetInterface.java
public interface TargetInterface {
public void method1();
public String method2();
public int method3(int x);
}
2. Target中實現了TargetInterface的3個方法
public class Target implements TargetInterface {
@Override
public void method1() {
System.out.println("method1 running...");
}
@Override
public String method2() {
System.out.println("method2 running...");
return "method2";
}
@Override
public int method3(int x) {
return x;
}
}
3. 實現動態代理類方式一:
需要用到3個包
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
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); } }
4. 實現動態代理類方式二:
直接先建立實體類物件
final Target target = new Target();
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest2 {
public static void main(String[] args) {
final Target target = new Target();
//動態建立代理物件
TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
//被執行幾次?------- 看代理物件呼叫方法幾次
//代理物件呼叫介面相應方法 都是呼叫invoke
/*
* proxy:是代理物件
* method:代表的是目標方法的位元組碼物件
* args:代表是呼叫目標方法時引數
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//反射知識點
Object invoke = method.invoke(target, args);//目標物件的相應方法
//retrun返回的值給代理物件
return invoke;
}
}
);
proxy.method1();//呼叫invoke---Method:目標物件的method1方法 args:null 返回值null
String method2 = proxy.method2();//呼叫invoke---Method:目標物件的method2方法 args:null 返回值method2
int method3 = proxy.method3(100);////呼叫invoke-----Method:目標物件的method3方法 args:Object[]{100} 返回值100
System.out.println(method2);
System.out.println(method3);
}
}