关于动态代理:动态代理实例

7次阅读

共计 1328 个字符,预计需要花费 4 分钟才能阅读完成。

作者:易哥
链接:https://zhuanlan.zhihu.com/p/…
起源:知乎
著作权归作者所有。商业转载请分割作者取得受权,非商业转载请注明出处。

1 动静代理

动静代理的实现形式罕用的有两种:

  • 反射实现:基于反射实现,指标对象必须要有接口。生成的代理类是接口的一个实现类
  • Cglib 实现:基于字节码实现,效率稍低,但指标对象不须要有接口。生成的代理类是指标类的子类,因而指标类不能是 final 的。

2 背景介绍
在 Java 中 java.lang.reflect 包下提供了一个 Proxy 类和一个 InvocationHandler 接口,通过应用这个类和接口就能够生成动静代理对象,只能针对接口做代理。
接口和指标类没有任何变动,只不过为了减少难度,咱们减少了返回值。
接口如下,除了减少了办法的返回值外无任何变动:

指标类如下,无任何变动:

2 反射调用办法

接下来,咱们应用 JDK 实现动静代理,对于代理类只须要实现 InvocationHandler 接口即可,并且要实现其中的 invoke()办法。
invoke()中须要传入指标对象、指标对象的办法、调用指标所需的参数,传入后,就会间接调用指定对象的指定办法了。

咱们应用举例:

咱们只有创立一个 ProxyHandler 对象,间接调用 invoke 办法,传入其中所须要的对象、办法、参数,便能够执行咱们写好的 invoke 办法,并且 invoke 中还能够调用指定对象的指定办法。这种办法非常灵活,ProxyHandler 建设后,调用 invoke 办法时,能够传入任何对象、任何办法,十分自在。
这种操作只是通过反射调用的指定对象的指定办法,并没有应用代理。然而能够用它来实现动静代理。咱们只有生成一个代理对象,接口所有的操作都由代理对象来实现。其中,代理对象中再通过这种反射的形式去调用指标对象即可了。

3 动静代理

在应用动静代理时,ProxyHandler 须要稍加革新,即在构造方法中传入指标对象。然而这里要留神的是,与动态代理不同,这里的指标对象的类型是任意的,因而同一个 ProxyHandler 能够用来代理不同的指标对象。

在应用时,如下:

首先,咱们定义了被代理的类的实例,并且传给了 proxyHandler。而后,咱们咱们间接调用了 Proxy 的静态方法 newProxyInstance 生成了一个接口的实例,这个实例就是代理(而且它晓得它代理的是 user 对象,初始化时曾经传给它了)。
而后,间接对这个实例调用办法就能够了,对这个接口调用办法,就相当于执行了 invoke 中的操作,输入如下:

pre words
hello Lily
post words

留神,在这种实现中,指标类 target 是在初始化时写死,并且在 invoke 时间接调用的,如果在 invoke 中间接调用传来的 proxy 对象,则会引发循环调用,造成死循环。
咱们查看下 Proxy 类中的静态方法,newProxyInstance 办法:

该办法用来返回指定接口的一个代理类实例。
输出参数有:

  • 生成代理类实例的 classLoader;
  • 要满足的接口;
  • 代理类的处理器,即具体的实现。

这样就指明了用哪个处理器解决哪个接口中的操作,以及该对象如何生成进去。
生成的对象就是一个代理对象,就能够代理接口的操作了。

正文完
 0