1動態(tài)代理
代理模式是給一個對象提供一個代理,以控制對它的訪問,如只有授權(quán)用戶才可以訪問某個對象,給對象添加日志功能。
動態(tài)代理是提供運行時實現(xiàn)代理模式的一種方法。
2 動態(tài)代理結(jié)構(gòu)圖

如上圖所示,當(dāng)要用到代理對象時,需調(diào)用代理產(chǎn)生器創(chuàng)建一個代理類來控制被代理的對象。
代理產(chǎn)生器的功能在JDK中也就是通過Proxy.newProxyInstance來動態(tài)創(chuàng)建一個代理類。
3 動態(tài)代理在Java中的實現(xiàn)
假設(shè)有一個CarCompany接口,他具備制造汽車的功能makeCar();不同的廠商有不同的makeCar的實現(xiàn)?,F(xiàn)在通過動態(tài)代理來添加一個測試makeCar所消耗時間的功能。
1. CarCompany.java
Interface CarCompay{
Public void makeCar();
}
2. CarCompanyA.java
public class CarCompanyA implements CarCompany {
public void makeCar() {
System.out.println("Company A make a car!");
}
}
3. CarCompanyHandler.java
Public class CarCompany implements CarCompany{
CarCompany com;
public CarCompanyHandler(CarCompany a){
this.com = a;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(method.getName().equals("makeCar")){
System.out.println("time1:" + System.currentTimeMillis());
method.invoke(this.com,new Class[]{});
System.out.println("time2:" + System.currentTimeMillis());
}
return null;
}
}
4. Test.java
Public class Test{
Public static void main(String[] arg){
CarCompanyA a = new CarCompanyA();
CarCompanyHandler handler = new CarCompanyHandler(a);
//產(chǎn)生一個新的代理類
CarCompany com = (CarCompany) Proxy.newProxyInstance(Test.class
.getClassLoader(), new Class[] { CarCompany.class }, handler);
com.makeCar();
}
}
5. 代理產(chǎn)生器動態(tài)生成的類(Proxy.newProxyInstance產(chǎn)生的)
相信看了如下代碼后就會很清楚動態(tài)代理的執(zhí)行過程。
public final class XXXXX$proxy extends Proxy
implements CarCompany
{
public final void makeCar()
{
try
{
//調(diào)用InvocationHandler的invoke方法
super.h.invoke(this, m3, null);
return;
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
private static Method m3;
static
{
try
{
m3 = Class.forName("com.home.CarCompany").getMethod("makeCar", new Class[0]);
}
catch(NoSuchMethodException nosuchmethodexception)
{
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
}
catch(ClassNotFoundException classnotfoundexception)
{
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
}
public a$proxy(InvocationHandler invocationhandler)
{
super(invocationhandler);
}
}