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