小A:“代理分為哪些類?”
大B:“代理分為靜態代理與動態代理。”
小A:“按功能怎麼分類哩?”
大B:“按功能將代理的組成類分為:標的類、標的介面、攔截類、耦合類。”
下面以具本程式碼舉例說明。
1、靜態與動態代理的公共部分
packageproxy.orgmon;
/**
*
**AngelSoftware,Inc.
*Copyright(C):
*Description:
*TODO標的類
*
*RevisionHistory:
*
*/
publicclassTargetImplimplementsTarget1,Target2
{
publicvoiddoSomething()
{
System.out.println(“doSomething!”);
}
publicStringdo1(Stringmsg)
{
//TODOAuto-generatedmethodstub
System.out.println(do1:+msg);
return“thisisStringMehtod!”;
}
publicintdo2()
{
System.out.println(“do2!”);
return1000;
}
}
packageproxy.orgmon;
/**
*
*
*
*Copyright(C):
*
*Description:
*TODO標的介面
*
*RevisionHistory:
*wanginitialversion.
*
*
*/
publicinterfaceTarget1
{
voiddoSomething();
}
packageproxy.orgmon;
/**
*
*
*
*Copyright(C):
*
*Description:
*TODO標的介面
*
*RevisionHistory:
*wanginitialversion.
*
*
*/
publicinterfaceTarget2
{
Stringdo1(Stringmsg);
intdo2();
}
packageproxy.orgmon;
/**
*
*
*
*Description:
*TODO攔載類
*
*RevisionHistory:
*wanginitialversion.
*
*
*/
publicclassIntercept
{
publicvoidbefore()
{
System.out.println(“Before……”);
}
publicvoidafter()
{
System.out.println(“After.”);
}
}
2、靜態代理特徵部分
packageproxy.jingtai;
importproxy.orgmon.Intercept;
importproxy.orgmon.TargetImpl;
/**
*
**AngelSoftware,Inc.
*Copyright(C):
*
*Description:
*TODO耦合類(耦合是為了解耦)
*
*
*
*/
publicclassInvocation
{
publicObjectinvokeDoSomething()
{
TargetImplt=newTargetImpl();
Interceptp=newIntercept();
//呼叫真實的標的類的方法之前置入攔載類的方法
p.before();
//呼叫真實的標的類的方法
t.doSomething();
//呼叫真實的標的類的方法之後置入攔載類的方法
p.after();
returnnull;
}
}
packageproxy.jingtai;
/**
*
*
*
*Description:
*TODO靜態代理(這理只簡單地講一下,著重講動態代理)
*
*RevisionHistory:
*wanginitialversion.
*
*
*/
publicclassTest
{
publicstaticvoidmain(Stringargs[])
{
newInvocation().invokeDoSomething();
}
}
3、動態代理特徵部分
packageproxy.dongtai;
importjava.lang.reflect.InvocationHandler;
importjava.lang.reflect.Method;
importproxy.orgmon.Intercept;
importproxy.orgmon.TargetImpl;
/**
*
**AngelSoftware,Inc.
*Copyright(C):
*
*Description:
*TODO耦合類(耦合是為了解耦)
*
*RevisionHistory:
*wanginitialversion.
*
*
*/
publicclassInvocationimplementsInvocationHandler
{
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)
throwsThrowable
{
TargetImplt=newTargetImpl();
Interceptp=newIntercept();
if(args!=null&args.length……1)
{
//更改引數
args[0]=“paramvaluehaschanged”;
}
//呼叫真實的標的類的方法之前置入攔載類的方法
p.before();
//呼叫真實的標的類的方法
Objecto=method.invoke(t,args);
//呼叫真實的標的類的方法之後置入攔載類的方法
p.after();
returno;
}
}
packageproxy.dongtai;
importproxy.orgmon.Target1;
importproxy.orgmon.Target2;
/**
*
*
*
*Copyright(C):
*
*Description:
*TODO測試類
*
*
*
*/
publicclassTest
{
/**
*logic1與logic的共同邏輯
*@paramproxy代理
*/
privatestaticvoidpublicLogic(Objectproxy)
{
//對目標介面Target1代理的呼叫
System.out.println(“對目標介面Target1代理的呼叫”);
Target1t1=(Target1)proxy;
t1.doSomething();
System.out.println();
//對目標介面Target2的呼叫
System.out.println(“對目標介面Target2代理的呼叫”);
Target2t2=(Target2)proxy;
System.out.println(TargetMehoddo1return:“+t2.do1(”hello!));
System.out.println(TargetMehoddo2return:+t2.do2());
System.out.println();
System.out.println();
}
/**
*newClass[]{Target2.class,Target1.class}
*正常
*@return
*/
publicstaticvoidlogic1()
{
Invocationiv=newInvocation();
/*
*Proxy.newProxyInstance的引數說明
*引數1:類載入器(個人感覺這個引數有點多佘,這個引數完成可以去掉,不知當初他們為何要設這個引數幹麼)
*引數2:代理的標的介面。就是說,你要代理的標的類可能會實現多個介面,你可以有選擇性地代理這些介面
*引數3:InvocationHandler的實現類.InvocationHandler介面做用就是解耦,解開標的類與攔載類之間的耦合,使它們之間可以互不關心
*/
Objectproxy=java.lang.reflect.Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),newClass[]{Target2.class,Target1.class},iv);
publicLogic(proxy);
}
/**
*newClass[]{Target1.class}
*將會出異常,因為他沒有在引數中聲時自己要呼叫Target2介面,而後面卻又去呼叫
*@return
*/
publicstaticvoidlogic2()
{
Invocationiv=newInvocation();
/*
*Proxy.newProxyInstance的引數說明
*引數1:類載入器(個人感覺這個引數有點多佘,這個引數完成可以去掉,不知當初他們為何要設這個引數幹麼)
*引數2:代理的標的介面。就是說,你要代理的標的類可能會實現多個介面,你可以有選擇性地代理這些介面
*引數3:InvocationHandler的實現類.InvocationHandler介面做用就是解耦,解開標的類與攔載類之間的耦合,使它們之間可以互不關心
*/
Objectproxy=java.lang.reflect.Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),newClass[]{Target1.class},iv);
publicLogic(proxy);
}
publicstaticvoidmain(Stringargs[])
{
logic1();
logic2();
}
}