Java SE之旅_09_代理Proxy
2014-04-24 15:35
204 查看
在Java中,如何在不修改一个类的情况下对该类特定的方法执行特殊的任务呢?
Java提供了代理类Proxy来解决这种问题. 前提条件是被代理对象必须至少实现一个接口.
Proxy提供了静态方法newProxyInstance以创建代理对象,具体方法如下:
java.lang.reflect.Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
InvocationHandler h)
其中,第一个参数loader指定运行类的类加载器,第二个参数指定被代理的对象实现的所有接口,第三个是InvocationHandler
接口,必须实现invoke方法以对被代理对象的方法进行拦截.
下面是个使用代理的小例子.
1. 定义一个接口MyInterface, 该接口有两个未实现的方法:
2. 定义接口MyInterface的实现类MyInterfaceImpl:
3. 定义测试类,使用Proxy对被代理对象obj进行代理,拦截在obj上执行的所有方法:
运行结果:
在测试中,当执行句柄InvocationHandler的invoke方法拦截到impl的close方法时, 不执行close方法, 做到了在不修改原类MyInterfaceImpl的情况下对MyInterfaceImpl的close方法进行特殊处理,
这就是传说中的动态代理~~
当然,你也可以重新写个类继承MyInterfaceImpl,重写close方法,但是这样做会产生不少"没多大用途"的类,它们的职责只是为了修改一个方法...
而是用代理就比较灵活,体现了Java语言的动态代理机制.
Java提供了代理类Proxy来解决这种问题. 前提条件是被代理对象必须至少实现一个接口.
Proxy提供了静态方法newProxyInstance以创建代理对象,具体方法如下:
java.lang.reflect.Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
InvocationHandler h)
其中,第一个参数loader指定运行类的类加载器,第二个参数指定被代理的对象实现的所有接口,第三个是InvocationHandler
接口,必须实现invoke方法以对被代理对象的方法进行拦截.
下面是个使用代理的小例子.
1. 定义一个接口MyInterface, 该接口有两个未实现的方法:
public interface MyInterface { void sayHi(String name); boolean close(); }
2. 定义接口MyInterface的实现类MyInterfaceImpl:
public class MyInterfaceImpl implements MyInterface { @Override public void sayHi(String name) { System.out.println("hi! your name is: " + name); System.out.println(); } @Override public boolean close() { System.out.println("the method close() is running..."); return true; } }
3. 定义测试类,使用Proxy对被代理对象obj进行代理,拦截在obj上执行的所有方法:
public class ProxyDemo { public static void main(String[] args) { //创建被代理对象obj final Object obj = new MyInterfaceImpl(); //创建代理者,代理obj Object proxy = Proxy.newProxyInstance( ProxyDemo.class.getClassLoader(), // 指定该测试类的类加载器 // 被代理的对象实现的所有接口,此处只有MyInterface这个接口 new Class[]{MyInterface.class}, new InvocationHandler(){//执行方法的句柄,是一个接口,只有一个方法invoke //invoke方法拦截所有在被代理对象obj上执行的方法,包括参数 public Object invoke(Object proxy,Method method, Object[] args) throws Throwable { System.out.println("method's name = "+method.getName()); //拦截参数 if(null != args){ System.out.println("args[0] is : " + args[0].toString()); }else{ System.out.println("no args... "); } //拦截方法 if("close".equals(method.getName())){ System.out.println("********** 拦截到close方法,测试一下不执行该方法**********"); return false; }else{ //把参数args传给obj,通过反射调用obj的method方法 return method.invoke(obj, args); } } }); //将代理者强转成MyInterface,调用MyInterface定义的方法进行测试 MyInterface impl = (MyInterface)proxy; impl.sayHi("小明"); impl.close(); } }
运行结果:
在测试中,当执行句柄InvocationHandler的invoke方法拦截到impl的close方法时, 不执行close方法, 做到了在不修改原类MyInterfaceImpl的情况下对MyInterfaceImpl的close方法进行特殊处理,
这就是传说中的动态代理~~
当然,你也可以重新写个类继承MyInterfaceImpl,重写close方法,但是这样做会产生不少"没多大用途"的类,它们的职责只是为了修改一个方法...
而是用代理就比较灵活,体现了Java语言的动态代理机制.
相关文章推荐
- JAVA设计模式(09):结构型-代理模式(Proxy)
- JAVA设计模式(09):结构型-代理模式(Proxy)
- JAVA设计模式(09):结构型-代理模式(Proxy)
- 设计模式--代理模式(Proxy)
- 十、结构模式之代理(Proxy)模式
- 设计模式之Proxy模式(代理模式)
- InvocationHandler和Proxy(Class)的动态代理机制详解
- 设计模式之-代理模式(Proxy)
- Java 实现代理(Proxy)模式
- browsermob-proxy, 基于Java的代理服务
- 本地代理ARP(Local Proxy ARP )
- 设计模式实践(三)代理模式(Proxy)
- GAE上架设代理PROXY
- 3.代理模式(Proxy)
- 大话设计模式--代理模式 proxy
- Apache和Tomcat利用Proxy代理保持Session
- JAVA设计模式- 代理模式(Proxy)
- Qt之QNetworkProxy(网络代理)
- 设计模式(十一)代理模式Proxy(结构型)
- 设计模式(十一)代理模式Proxy(结构型)