相比于靜態(tài)代理策橘,動(dòng)態(tài)代理避免了開發(fā)人員編寫各個(gè)繁鎖的靜態(tài)代理類隧哮,只需簡(jiǎn)單地指定一組接口及目標(biāo)類對(duì)象就能動(dòng)態(tài)的獲得代理對(duì)象。
代理模式
使用代理模式必須要讓代理類和目標(biāo)類實(shí)現(xiàn)相同的接口,客戶端通過代理類來調(diào)用目標(biāo)方法讲弄,代理類會(huì)將所有的方法調(diào)用分派到目標(biāo)對(duì)象上反射執(zhí)行,還可以在分派過程中添加"前置通知"和后置處理(如在調(diào)用目標(biāo)方法前校驗(yàn)權(quán)限依痊,在調(diào)用完目標(biāo)方法后打印日志等)等功能避除。
使用動(dòng)態(tài)代理的五大步驟
-1.通過實(shí)現(xiàn)InvocationHandler接口來自定義自己的InvocationHandler;
-2.通過Proxy.getProxyClass獲得動(dòng)態(tài)代理類
-3.通過反射機(jī)制獲得代理類的構(gòu)造方法,方法簽名為getConstructor(InvocationHandler.class)
-4.通過構(gòu)造函數(shù)獲得代理對(duì)象并將自定義的InvocationHandler實(shí)例對(duì)象傳為參數(shù)傳入
-5.通過代理對(duì)象調(diào)用目標(biāo)方法
動(dòng)態(tài)代理的使用
package com.cayden.collect.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* Created by cuiran on 16/6/20.
*/
public class MyProxy {
public interface IHello{
void sayHello();
}
static class Hello implements IHello{
@Override
public void sayHello() {
System.out.println("Hello World");
}
}
static class MyInvocationHandler implements InvocationHandler{
private Object target;//目標(biāo)對(duì)象
public MyInvocationHandler(Object target){
this.target=target;
}
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
System.out.println("before");
Object rs=method.invoke(target,args);
System.out.println("after");
return rs;
}
}
public static void main(String [] args){
// System.out.println("test");
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
IHello iHello=(IHello) Proxy.newProxyInstance(IHello.class.getClassLoader(),//加載接口的類加載器
new Class[]{IHello.class},
new MyInvocationHandler(new Hello()));
iHello.sayHello();
}
}
輸出結(jié)果
before
Hello World
after