书城计算机大话设计模式
11030400000080

第80章 5 代理分类

小A:“代理分为哪些类?”

大B:“代理分为静态代理与动态代理。”

小A:“按功能怎么分类哩?”

大B:“按功能将代理的组成类分为:标的类、标的接口、拦截类、耦合类。”

下面以具本代码举例说明。

1、静态与动态代理的公共部分

package proxy。common;

/ *

**AngelSoftware,Inc。

*Copyright(C):

*Description:

*TODO 标的类

*

*Revision History:

*

*/

public class TargetImpl implements Target1,Target2

{

public void doSomething()

{

System。out。println(“doSomething!”);

}

public String do1(String msg)

{

//TODO Auto-generated method stub

System。out。println(do1: msg);

return“this is String Mehtod!”;

}

public int do2()

{

System。out。println(“do2!”);

return 1000;

}

}

package proxy。common;

/ *

*

*

*Copyright(C):

*

*Description:

*TODO 标的接口

*

*Revision History:

*wanginitial version。

*

*

*/

public interface Target1

{

void doSomething();

}

package proxy。common;

/ *

*

*

*Copyright(C):

*

*Description:

*TODO 标的接口

*

*Revision History:

*wang initial version。

*

*

*/

public interface Target2

{

String do1(String msg);

int do2();

}

package proxy。common;

/ *

*

*

*Description:

*TODO 拦载类

*

*Revision History:

*wang initial version。

*

*

*/

public class Intercept

{

public void before()

{

System。out。println(“Before……”);

}

public void after()

{

System。out。println(“After。”);

}

}

2、静态代理特征部分

package proxy。jingtai;

import proxy。common。Intercept;

import proxy。common。TargetImpl;

/ *

**AngelSoftware,Inc。

*Copyright(C):

*

*Description:

*TODO 耦合类(耦合是为了解耦)

*

*

*

*/

public class Invocation

{

public Object invokeDoSomething()

{

TargetImpl t=new TargetImpl();

Intercept p=new Intercept();

//调用真实的标的类的方法之前置入拦载类的方法

p。before();

//调用真实的标的类的方法

t。doSomething();

//调用真实的标的类的方法之后置入拦载类的方法

p。after();

return null;

}

}

package proxy。jingtai;

/ *

*

*

*Description:

*TODO 静态代理(这理只简单地讲一下,着重讲动态代理)

*

*Revision History:

*wang initial version。

*

*

*/

public class Test

{

public static void main(String args[])

{

new Invocation()。invokeDoSomething();

}

}

3、动态代理特征部分

package proxy。dongtai;

import java。lang。reflect。InvocationHandler;

import java。lang。reflect。Method;

import proxy。common。Intercept;

import proxy。common。TargetImpl;

/ *

**AngelSoftware,Inc。

*Copyright(C):

*

*Description:

*TODO 耦合类(耦合是为了解耦)

*

*Revision History:

*wang initial version。

*

*

*/

public class Invocation implements InvocationHandler

{

public Object invoke(Object proxy,Method method,Object[]args)

throws Throwable

{

TargetImpl t=new TargetImpl();

Intercept p=new Intercept();

if(args!=null&args。length……1)

{

//更改参数

args[0]=“param value has changed”;

}

//调用真实的标的类的方法之前置入拦载类的方法

p。before();

//调用真实的标的类的方法

Object o=method。invoke(t,args);

//调用真实的标的类的方法之后置入拦载类的方法

p。after();

return o;

}

}

package proxy。dongtai;

import proxy。common。Target1;

import proxy。common。Target2;

/ *

*

*

*Copyright(C):

*

*Description:

*TODO 测试类

*

*

*

*/

public class Test

{

/ *logic1与logic的共同逻辑

*@param proxy 代理

*/

private static void publicLogic(Object proxy)

{

//对目标接口Target1代理的调用

System。out。println(“对目标接口Target1代理的调用”);

Target1 t1=(Target1)proxy;

t1.doSomething();

System。out。println();

//对目标接口Target2的调用

System。out。println(“对目标接口Target2代理的调用”);

Target2 t2=(Target2)proxy;

System。out。println(Target Mehod do1 return:“ t2.do1(”hello!));

System。out。println(Target Mehod do2 return: t2.do2());

System。out。println();

System。out。println();

}

/ *new Class[]{Target2.class,Target1.class}

*正常

*@return

*/

public static void logic1()

{

Invocation iv=new Invocation();

/*

*Proxy。newProxyInstance的参数说明

*参数1:类加载器(个人感觉这个参数有点多佘,这个参数完成可以去掉,不知当初他们为何要设这个参数干么)

*参数2:代理的标的接口。就是说,你要代理的标的类可能会实现多个接口,你可以有选择性地代理这些接口

*参数3:InvocationHandler的实现类。InvocationHandler接口做用就是解耦,解开标的类与拦载类之间的耦合,使它们之间可以互不关心

*/

Object proxy=java。lang。reflect。Proxy。newProxyInstance(Thread。currentThread()。getContextClassLoader(),new Class[]{Target2.class,Target1.class},iv);

publicLogic(proxy);

}

/ *new Class[]{Target1.class}

*将会出异常,因为他没有在参数中声时自己要调用Target2接口,而后面却又去调用

*@return

*/

public static void logic2()

{

Invocation iv=new Invocation();

/*

*Proxy。newProxyInstance的参数说明

*参数1:类加载器(个人感觉这个参数有点多佘,这个参数完成可以去掉,不知当初他们为何要设这个参数干么)

*参数2:代理的标的接口。就是说,你要代理的标的类可能会实现多个接口,你可以有选择性地代理这些接口

*参数3:InvocationHandler的实现类。InvocationHandler接口做用就是解耦,解开标的类与拦载类之间的耦合,使它们之间可以互不关心

*/

Object proxy=java。lang。reflect。Proxy。newProxyInstance(Thread。currentThread()。getContextClassLoader(),new Class[]{Target1.class},iv);

publicLogic(proxy);

}

public static void main(String args[])

{

logic1();

logic2();

}

}