Java 動態代理類的實現


1、動態代理:為目標對象創建一個代理類,該代理類擁有目標對象的方法,屬性,同時也可添加自己的方法,比如:日志的添加、校驗等。

2、實現條件:在java中規定,要想產生一個對象的代理對象,那么這個對象必須要有一個接口,所以我們第一步就是設計這個對象的接口,在接口中定義這個對象所具有的行為(方法)

2、應用場景:當用戶要調用一個類的方法時,用戶可以通過調用代理,代理通過接口調用原來的類的方法,代理在把方法給用戶前可以添加一些方法,如錯誤日志,用戶類的方法運行的時間來監聽類方法的性能。當代理完成時候就是當代理調用方法時候,就會啟動InvocationHandler里的invoke方法(在測試類中代理類調用方法時有所體現)

3、實例關鍵點:java在JDK1.5之后提供了一個"java.lang.reflect.Proxy"類,通過"Proxy"類提供的一個newProxyInstance方法用來創建一個對象的代理對象,如下所示:

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 

newProxyInstance方法用來返回一個代理對象,這個方法總共有3個參數,
ClassLoader loader用來指明生成代理對象使用哪個類裝載器,
Class<?>[] interfaces用來指明生成哪個對象的代理對象,通過接口指定,
InvocationHandler h用來指明產生的這個代理對象要做什么事情。
所以我們只需要調用newProxyInstance方法就可以得到某一個對象的代理對象了。

4、實例如下:
1、目標對象接口:
public interface People {

/**
* 唱歌
* @param name
* @return
*/
public String sing(String name);

/**
* 跳舞
* @param name
* @return
*/
public String dance(String name);

}
2、實現接口的目標對象

/**
* 目標類對象
*/
public class LiuDeHua implements People{

@Override
public String sing(String name) {

return "唱"+name+"歌!好聽!";
}

@Override
public String dance(String name) {
return "跳"+name+"舞!好看!";
    }
}
3、代理類的實現
/**
* 目標類(LiuDeHua)代理類
*/
public class LiuDeHuaProxy {
//類變量,代理類要代理的目標對象
private People ldh = new LiuDeHua();

public People getProxy() {
return (People) Proxy.newProxyInstance(LiuDeHuaProxy.class
.getClassLoader(), ldh.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
//此處可添加目標對象以外的方法。。。

//如果調用的是代理對象的sing方法
if (method.getName().equals("sing")) {

return method.invoke(ldh, args); //代理對象調用真實目標對象的sing方法去處理用戶請求
}
//如果調用的是代理對象的dance方法
if (method.getName().equals("dance")) {

return method.invoke(ldh, args);//代理對象調用真實目標對象的dance方法去處理用戶請求
}

return null;
}
});
}

}
4、測試動態代理類調用過程
public class Test {
public static void main(String[] args) {
//代理類
LiuDeHuaProxy proxy = new LiuDeHuaProxy();

//獲得代理對象
People p = proxy.getProxy();

//調用代理對象的sing方法
String retValue = p.sing("冰雨");
System.out.println(retValue);

//調用代理對象的dance方法
String value = p.dance("江南style");
System.out.println(value);
}

}
5、博文學習借鑒:https://www.cnblogs.com/xdp-gacl/p/3971367.html
 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM