做者:易哥
连接:https://zhuanlan.zhihu.com/p/...
来源:知乎
著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。java
动态代理的实现方式经常使用的有两种:post
2 背景介绍
在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,经过使用这个类和接口就能够生成动态代理对象,只能针对接口作代理。
接口和目标类没有任何变化,只不过为了增长难度,咱们增长了返回值。
接口以下,除了增长了方法的返回值外无任何变化: spa
目标类以下,无任何变化: 3d
接下来,咱们使用JDK完成动态代理,对于代理类只须要实现InvocationHandler接口便可,而且要实现其中的invoke()方法。
invoke()中须要传入目标对象、目标对象的方法、调用目标所需的参数,传入后,就会直接调用指定对象的指定方法了。 代理
咱们使用举例: code
咱们只要建立一个ProxyHandler对象,直接调用invoke方法,传入其中所须要的对象、方法、参数,即可以执行咱们写好的invoke方法,而且invoke中还能够调用指定对象的指定方法。这种方法很是灵活,ProxyHandler创建后,调用invoke方法时,能够传入任何对象、任何方法,很是自由。
这种操做只是经过反射调用的指定对象的指定方法,并无使用代理。可是能够用它来实现动态代理。咱们只要生成一个代理对象,接口全部的操做都由代理对象来完成。其中,代理对象中再经过这种反射的方式去调用目标对象便可了。对象
在使用动态代理时,ProxyHandler须要稍加改造,即在构造方法中传入目标对象。可是这里要注意的是,与静态代理不一样,这里的目标对象的类型是任意的,所以同一个ProxyHandler能够用来代理不一样的目标对象。 blog
在使用时,以下: 接口
首先,咱们定义了被代理的类的实例,而且传给了proxyHandler。而后,咱们咱们直接调用了Proxy的静态方法newProxyInstance生成了一个接口的实例,这个实例就是代理(并且它知道它代理的是user对象,初始化时已经传给它了)。
而后,直接对这个实例调用方法就能够了,对这个接口调用方法,就至关于执行了invoke中的操做,输出以下:rem
pre words hello Lily post words
注意,在这种实现中,目标类target是在初始化时写死,而且在invoke时直接调用的,若是在invoke中直接调用传来的proxy对象,则会引起循环调用,形成死循环。
咱们查看下Proxy类中的静态方法,newProxyInstance方法:
该方法用来返回指定接口的一个代理类实例。
输入参数有:
这样就指明了用哪一个处理器处理哪一个接口中的操做,以及该对象如何生成出来。 生成的对象就是一个代理对象,就能够代理接口的操做了。