Java代理笔记
Posted _路上
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java代理笔记相关的知识,希望对你有一定的参考价值。
代理顾名思义,就是一个中间层,当我们要使用某个方法时,不直接调用,而是告诉代理,让代理替我们去请求方法,并返回结果。在这个过程中,我们只知道代理执行并返回给了我们操作结果,至于它有没有其他操作并不知道,但这个也无关紧要,因为不管代理在请求实际方法之前和之后做了什么,对我们都不会产生任何影响。由于代理的这个特性,可以用来进行记录日志等操作。
代理分为静态代理和动态代理。
静态代理
静态代理需要我们在调用者和具体的执行者之间创建一个代理类,其实现需要被代理的接口并持有一个此接口,具体代码如下:
接口类(被代理):
public interface Hello { void say(String name); }
代理类:
public class HelloProxy implements Hello { ? private Hello helloImpl; ? public HelloProxy() { this.helloImpl = new HelloImpl(); // HelloImpl为一个Hello接口的一个普通实现类 } ? @Override public void say(String name) { System.out.println("before say"); helloImpl.say(name); System.out.println("after say"); } }
使用的时候只需要new一个代理类赋值给接口即可:Hello hello = new HelloProxy()
,之后的执行会由代理类去负责。但是这么做有一个问题就是对每个需要代理的类,都需要创建一个对应的代理类,即使代理类的逻辑都是相似的,动态代理就是解决这个问题的。
动态代理
动态代理相当于在调用者和代理类之间又增加了一个中间层,在这个中间层中完成代理类的逻辑,达到复用代码的效果。这个中间层需要实现InvocationHandler
接口,并持有一个被代理的类,大致代码如下:
public class Myproxy implements InvocationHandler { ? private Object target; // 被代理的类 ? public Myproxy(Object target) { this.target = target; } ? @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before invoke"); // 执行代理的方法前进行的操作 Object invoke = method.invoke(target, args); // 调用执行被代理的方法 System.out.println("after invoke"); // 执行代理的方法后进行的操作 return invoke; // 返回方法执行结果 } }
使用时,使用Proxy的静态方法获取代理类,将其强转为对应的接口,之后可以同静态代理类同样使用。
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
其中loader为类加载器,interfaces为要代理的接口,h为之前定义的实现InvocationHandler
接口的类的实例。
这个方法会返回一个代理类,其实现的要代理的接口,并持有一个实现InvocationHandler
接口的实例,代理类的代码大致如下:
public final class $Proxy0 extends Proxy implements Hello { ? public $Proxy0(InvocationHandler paramInvocationHandler) { super(paramInvocationHandler); } ? public final String say() { try { return ((String)this.h.invoke(this, m3, null)); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } ? }
如上代码我们可以将其强转为Hello接口,实际调用的时候会调用InvocationHandler
实现类中的invoke
方法,而其中就是我们实现的代理业务,当然,也包括实际的业务。
以上是关于Java代理笔记的主要内容,如果未能解决你的问题,请参考以下文章
[原创]java WEB学习笔记61:Struts2学习之路--通用标签 property,uri,param,set,push,if-else,itertor,sort,date,a标签等(代码片段