一、什麼是動態代理
一個服務或者是一個功能,一個對象。由於某種自身或者外界的原因,不能直接暴露出來,而是需要另外一個對象做一下跳轉(也不一定是完全的跳轉)。並且在這個過程中,最終實現功能或者是解決問題的實體並沒有發生改變。
光說概念的話會比較抽象,我們舉幾個生活中的例子:
房產中介
如果戶主打算拍賣掉房子,因此需要每天接待買家看房,和買家討價還價。但是戶主需要和每一個買家都進行接觸。每增加一個新的買家,他就需要重新與之交接。
因此就需要引入一個代理:房產中介。
戶主將房子的信息交給中介。中介將所有的信息進行處理後公佈出來。買房人再從中介處獲取到自己所需要的信息,然後再通過中介與賣家溝通。
這樣賣家就不需要跟每一個買房人都進行交流。只需要按照事先自己考慮的結果與中介進行商議即可。
二、JDK動態代理
JDK動態代理是代理模式的一種實現方式,只能代理接口。JDK動態代理通過反射虛擬化代理對象(不需要生成代理類)實現InvocationHandler 就可以了。
三、如何使用
1.創建一個接口BankService,在接口裏聲明一個transfer(轉賬)方法,代碼如下
public Interface BankService {
public void transfer(String source , String target , BigDecimal money);
}
2.創建接口的實現類BankServiceImpl,實現接口的方法
public class BankServiceImpl implements BankService{
public void transfer(String source, String target, BigDecimal money) {
System.out.println(source+"向"+target+"轉賬"+money);
}
}
3.創建代理類ObjProxy,實現接口 InvocationHandler,代碼如下
public class ObjProxy implements InvocationHandler{
//target是目標代理對象
private Object target;
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName()+"被執行,參數如下");
//args是被代理函數的參數列表
for(Object o :args) {
System.out.println(o);
}
return method.invoke(target, args);
}
public Object createProxy(Object target) {
this.target = target;
//第一個參數是獲取被代理類的類加載器,第二個參數是獲取該類所實現的所有接口,第三個參數是InvocationHandler的實現類對象
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
}
4.Main類中調用
public class Main {
public static void main(String[] args) {
//bs:被代理對象 bsProxy:代理對象
BankService bs = new BankServiceImpl();
BankService bsProxy = (BankService) new ObjProxy().createProxy(bs);
bsProxy.transfer("張三", "李四", new BigDecimal("367.1462"));
}
}
5.結果如下:
transfer被執行,參數如下
張三
李四
367.1462
張三向李四轉賬367.1462