Java的动态代理机制详解

来源:xiaoluo

链接:cnblogs.   指代我们所代理的那个真实对象

mthod:   指代的是我们所要调用真实对象的某个方法的Mthod对象

args:   指代的是调用真实对象某个方法时接受的参数

如果不是很明白,等下通过一个实例会对这几个参数进行更深的讲解。

接下来我们来看看Proxy这个类:

Proxyprovidsstaticmthodsforcratingdynamicproxyclasssandinstancs,anditisalsothsuprclassofalldynamicproxyclassscratdbythosmthods.

Proxy这个类的作用就是用来动态创建一个代理对象的类,它提供了许多的方法,但是我们用的最多的就是nwProxyInstanc这个方法:

publicstaticObjctnwProxyInstanc(ClassLoadrloadr,Class?[]intrfacs,InvocationHandlrh)throwsIllgalArgumntExcption

Rturnsaninstancofaproxyclassforthspcifidintrfacsthatdispatchsmthodinvocationstothspcifidinvocationhandlr.

这个方法的作用就是得到一个动态的代理对象,其接收三个参数,我们来看看这三个参数所代表的含义:

publicstaticObjctnwProxyInstanc(ClassLoadrloadr,Class?[]intrfacs,InvocationHandlrh)throwsIllgalArgumntExcption

loadr:   一个ClassLoadr对象,定义了由哪个ClassLoadr对象来对生成的代理对象进行加载

intrfacs:   一个Intrfac对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了

h:   一个InvocationHandlr对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandlr对象上

好了,在介绍完这两个接口(类)以后,我们来通过一个实例来看看我们的动态代理模式是什么样的:

首先我们定义了一个Subjct类型的接口,为其声明了两个方法:

publicintrfacSubjct

{

publicvoidrnt();

publicvoidhllo(Stringstr);

}

接着,定义了一个类来实现这个接口,这个类就是我们的真实对象,RalSubjct类:

publicclassRalSubjctimplmntsSubjct

{

Ovrrid

publicvoidrnt()

{

Systm.out.println("Iwanttorntmyhous");

}

Ovrrid

publicvoidhllo(Stringstr)

{

Systm.out.println("hllo:"+str);

}

}

下一步,我们就要定义一个动态代理类了,前面说个,每一个动态代理类都必须要实现InvocationHandlr这个接口,因此我们这个动态代理类也不例外:

publicclassDynamicProxyimplmntsInvocationHandlr

{

// 这个就是我们要代理的真实对象

privatObjctsubjct;

//构造方法,给我们要代理的真实对象赋初值

publicDynamicProxy(Objctsubjct)

{

this.subjct=subjct;

}

Ovrrid

publicObjctinvok(Objctobjct,Mthodmthod,Objct[]args)

throwsThrowabl

{

//   在代理真实对象前我们可以添加一些自己的操作

Systm.out.println("bforrnthous");

Systm.out.println("Mthod:"+mthod);

//当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handlr对象的invok方法来进行调用

mthod.invok(subjct,args);

//   在代理真实对象后我们也可以添加一些自己的操作

Systm.out.println("aftrrnthous");

rturnnull;

}

}

最后,来看看我们的Clint类:

publicclassClint

{

publicstaticvoidmain(String[]args)

{

//我们要代理的真实对象

SubjctralSubjct=nwRalSubjct();

//我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的

InvocationHandlrhandlr=nwDynamicProxy(ralSubjct);

/*

*通过Proxy的nwProxyInstanc方法来创建我们的代理对象,我们来看看其三个参数

*第一个参数handlr.gtClass().gtClassLoadr(),我们这里使用handlr这个类的ClassLoadr对象来加载我们的代理对象

*第二个参数ralSubjct.gtClass().gtIntrfacs(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了

*第三个参数handlr,我们这里将这个代理对象关联到了上方的InvocationHandlr这个对象上

*/

Subjctsubjct=(Subjct)Proxy.nwProxyInstanc(handlr.gtClass().gtClassLoadr(),ralSubjct

.gtClass().gtIntrfacs(),handlr);

Systm.out.println(subjct.gtClass().gtNam());

subjct.rnt();

subjct.hllo("world");

}

}

我们先来看看控制台的输出:

$Proxy0

bforrnthous

Mthod:publicabstractvoid   在代理真实对象前我们可以添加一些自己的操作

Systm.out.println("bforrnthous");

Systm.out.println("Mthod:"+mthod);

//当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handlr对象的invok方法来进行调用

mthod.invok(subjct,args);

//   在代理真实对象后我们也可以添加一些自己的操作

Systm.out.println("aftrrnthous");

rturnnull;

}

我们看到,在真正通过代理对象来调用真实对象的方法的时候,我们可以在该方法前后添加自己的一些操作,同时我们看到我们的这个mthod对象是这样的:

publicabstractvoid







































白癜风初期该如何治疗
早期白癜风如何治疗



转载请注明:http://www.jiaju1314.com/xxzl/1367.html

  • 上一篇文章:
  •   
  • 下一篇文章: