JAVA反射_代理
来源:互联网 发布:电脑实用软件推荐 编辑:程序博客网 时间:2024/06/07 06:21
一、什么是动态代理
动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实。代理一般会实现它所表示的实际对象的接口。代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统的实际功能,代理对象对客户隐藏了实际对象。客户不知道它是与代理打交道还是与实际对象打交道。
目的:主要用来做方法的增强,让你可以在不修改源码(不用改变这个方法的签名,原来调用这个方法的类依然能正常工作)的情况下,增强一些方法。在方法执行前后做任何你想做的事情(甚至根本不去执行这个方法),因为在InvocationHandler的invoke方法中,你可以直接获取正在调用方法对应的Method对象,具体应用的话,比如可以添加调用日志,做事务控制等。
还有一个有趣的作用是可以用作远程调用,比如现在有Java接口,这个接口的实现部署在其它服务器上,在编写客户端代码的时候,没办法直接调用接口方法,因为接口是不能直接生成对象的,这个时候就可以考虑代理模式(动态代理)了,通过Proxy.newProxyInstance代理一个该接口对应的InvocationHandler对象,然后在InvocationHandler的invoke方法内封装通讯细节就可以了。具体的应用,最经典的当然是Java标准库的RMI,其它比如hessian,各种webservice框架中的远程调用,大致都是这么实现的。
而像 AspectJ 这种 AOP 刚不同,它直接把人家的 class 代码修改了,它就不需要使用代理。
这些在新的 JDK 6 中都可以通过 Instrument 来做到,不过也是个通用的方法,还得通过规则来定制什么情况下处理,什么时候不处理。
二、jdk的动态代理
目前Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。 其实现主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。
Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现。
动态代理是很多框架和技术的基础, spring 的AOP实现就是基于动态代理实现的。了解动态代理的机制对于理解AOP的底层实现是很有帮助的。
平常写的代码,一般是一个对象直接持有另外一个对象的引用,称为
静态代理:
public class StaticProxyMain { //这里传入的是接口类型的对象,方便向上转型,实现多态 public static void consumer(ProxyInterface pi){ pi.say(); } public static void main(String[] args) { StaticProxyMain.consumer(new ProxyObject()); }}//代理接口interface ProxyInterface{ void say();}//被代理者class RealObject implements ProxyInterface{ //实现接口方法 @Override public void say() { System.out.println("say"); }}//代理者class ProxyObject implements ProxyInterface{ @Override public void say() { System.out.println("hello proxy"); new RealObject().say(); System.out.println("this is method end"); }}
动态代理:
例子1:
public class DProxyMain { public static void main(String[] args) { ArrayList<String> content = new ArrayList<>(); MyInvocationHandler handler = new MyInvocationHandler(content); Object proxy = Proxy.newProxyInstance(null, new Class[]{List.class}, handler); if (proxy instanceof List) { System.out.println("proxy is list"); List<String> mlist = (List<String>) proxy; mlist.add("one"); mlist.add("two"); mlist.add("three"); mlist.add("apple"); } System.out.println("proxy:"+proxy.toString()); System.out.println("content:"+content.toString()); }}class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("method name:"+method.getName()); if (method.getName().equals("add")) { if (args[0].equals("apple")) { return false; } } return method.invoke(this.target, args); }}
例子2:
public class DynamicProxyMain { public static void main(String[] args) { RealObject realObject = new RealObject(); ProxyInterface proxyInterface = (ProxyInterface) Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(), new Class[]{ProxyInterface.class}, new ProxyObject(realObject)); proxyInterface.say(); }}//代理接口interface ProxyInterface{ void say();}//被代理类class RealObject implements ProxyInterface { @Override public void say() { System.out.println("I'm talking..."); }}//代理类,实现InvocationHandler 接口class ProxyObject implements InvocationHandler { private Object target = null; public ProxyObject(Object proxied){ this.target = proxied; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("method name:"+method.getName()); return method.invoke(this.target, args); }}
1. 利用动态代理实现设计模式,修饰器和适配器
2. AOP编程(Spring AOP)
- JAVA反射_代理
- 反射_类加载器_代理
- java 反射和代理
- JAVA 反射和代理
- Java 反射和代理
- java反射代理技术
- JAVA反射与代理
- java反射代理学习
- Java 反射-动态代理
- Java反射与代理
- java反射之代理
- java反射代理学习
- Java反射与代理
- java动态代理、反射
- java 反射机制、代理
- java反射与代理
- java反射代理机制
- Java基础知识_反射
- 每日一练27
- 深入理解javascript原型和闭包(5)——instanceof
- redis
- HTTP长连接与短连接
- 基于Linux操作系统
- JAVA反射_代理
- Android加密之文件级加密
- 客户端HttpClient4处理 Servlet Gzip后的内容
- android指定签名的apk才能安装
- >吴恩达机器学习笔记(1)
- SpringMVC+ibatis
- 使用 Azure 门户创建 Linux 虚拟机
- 程序时间随当前系统时间变化
- 每日一练28