黑马程序员--动态代理
来源:互联网 发布:可用的数据接口 编辑:程序博客网 时间:2024/05/16 15:57
什么是动态代理
A接口有C方法,类B实现A接口,原本应该是执行B类中的C方法,可现在不这样做;现在声明产生B类的代理类B1,有它来冒充B类的“兄弟”并“实现”A接口。对外界来说B1应该也有C方法,可当真正调用它的时候,它会去执行与它关联InvocationHandler的invoke()方法,在这个方法里面你可以做很多事情。这样,这个请求就被“代理”到其它地方去了。
代理模式:
代理模式是常用的Java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
反射与动态代理
动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java反射机制可以生成任意类型的动态代理类。Java.lang.reflect包中的Proxy类和InvocationHandler接口提供了生成动态代理类的能力。
反射与动态代理中包含一个类和一个接口:
InvocationHandler接口:public interface InvocationHandler{public Object invoke(Object proxy,Method method,Object[] arge)throws Throwable;}参数说明:
Object proxy:只被代理的对象。
Method method:要调用的方法
Object[] args:方法调用时所需要的参数。
Proxy类:
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法:
public static Object newProxyInstance(ClassLoadr loader,Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException参数说明:
ClassLoader loader:类加载器
Class<?>[] interface:得到全部的接口
InvocationHandler h:得到InvocationHandler接口的子类实例
。
如图:这张图很精辟的描述了动态代理的工作原理。当客户端调用代理类,代理类的构造方法接收一个InvocationHandler的对象,接着客户端调用代理类的各个方法,各个方法会把代理的调用请求转发给刚才通过构造方法传进去的InvocationHandler对象,那么InvocationHandler对象就会把请求分发给目标的相应方法。
下面通过代码实例来证明动态代理的强大功能。
<创建的接口类>
package com.xy.studyproxytest;public interface Hello { void hello(String name);}<创建的被代理类>
package com.xy.studyproxytest;public class HelloSpeaker implements Hello { @Override public void hello(String name) { System.out.printf("哈喽,%s%n",name); }}<创建的代理类>
package com.xy.studyproxytest;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.logging.Level;import java.util.logging.Logger;public class LoggingHandler implements InvocationHandler { private Object target; public Object bind(Object target){ this.target = target; //动态建立代理对象。 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this ); }//代理对象被调用会实现此方法。 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; log(String.format("%s() 调用开始。。。", method.getName())); result = method.invoke(target, args);//实现被代理对象的职责。 log(String.format("%s() 调用结束。。。", method.getName())); return result; } private void log(String message) { Logger.getLogger(LoggingHandler.class.getName()).log(Level.INFO,message); }}<执行类>
package com.xy.studyproxytest;public class ProxyDemo {/** *执行类 */public static void main(String[] args) {LoggingHandler loggingHandler = new LoggingHandler();Hello helloProxy = (Hello) loggingHandler.bind(new HelloSpeaker());helloProxy.hello("xuyan");}}<执行结果>
2014-5-8 12:09:17 com.xy.studyproxytest.LoggingHandler log信息: 我被黑马录取啦!!!hello() 调用开始。。。2014-5-8 12:09:17 com.xy.studyproxytest.LoggingHandler log信息: 我从黑马毕业上班啦!!!hello() 调用结束。。。哈喽,xuyan【总结】主要是使用Proxy.newProxyInstance()方法建立代理对象,调用时必须指定类加载器,告知要代理的接口,以及接口上定义方法被调用时的处理者(InvocationHandler实例)。Proxy.new ProxyInstance()方法底层会使用原生方法生成代理对象的Class实例,并利用它来生成代理对象,代理对象会操作指定要代理的接口。如果操作Proxy.newProxyInstance()返回的代理对象,在每次操作时会调用处理器(InvocationHandler实例)的invoke()方法,并传入代理对象、被调用方法的Method实例与参数值。可以在invoke()方法中实现日志,利用被代理对象、被调用的方法Method实例与参数值实现被代理对象的职责。
-------------------- Android培训、java培训、期待与您交流! ----------------------详细请查看:www.itheima.com
- 黑马程序员 动态代理
- 黑马程序员-动态代理
- 黑马程序员 动态代理
- 黑马程序员-动态代理
- 黑马程序员--动态代理
- 黑马程序员--动态代理
- 黑马程序员-动态代理
- 黑马程序员---------动态代理
- 黑马程序员-动态代理
- 黑马程序员-动态代理
- 黑马程序员-动态代理
- 黑马程序员 动态代理
- 黑马程序员-动态代理
- 黑马程序员------动态代理
- 黑马程序员 动态代理
- 黑马程序员----动态代理
- 黑马程序员-----动态代理
- 黑马程序员----动态代理
- unity3d如何有效地组织代码?
- PHP实现指定时间的n月之前的这一天的两种算法
- CVTRES : fatal error CVT1100: duplicate resource. type:DIALOG, name:1269, language:0x0804
- YII 的安全性演示代码SQL
- IOS高级教程1:处理1000张图片的内存优化
- 黑马程序员--动态代理
- 生活意味着什么?
- 动态规划
- Android中如何自己制作su
- 配置rhel 6.4(64位)安装使用syslog-ng 3.5
- matlab mosaic
- Linux BashShell 命令全称
- 卷积神经网络CNN介绍:结构框架,源码理解
- do{}while(0)的意义