大话设计模式
字体: 16 + -

第80章

小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();

}

}