a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 116|回复: 0

[专业语言] Java认证之Java实践用动态代理进行修饰(1)

[复制链接]
发表于 2012-8-4 12:44:44 | 显示全部楼层 |阅读模式
Java认证之Java实践用动态代理进行修饰
' ?3 @6 ]* T/ t动态代理工具 是 java.lang.reflect 包的一部分,在 JDK 1.3 版本中添加到 JDK,它允许程序创建代理对象,代理对象能实现一个或多个已知接口,并用反射代替内置的虚方法分派,编程地分派对接口方法的调用。这个过程允许实现“截取”方法调用,重新路由它们或者动态地添加功能。; e0 T8 K$ H1 K; p
动态代理为实现许多常见设计模式(包括 Facade、Bridge、Interceptor、Decorator、Proxy(包括远程和虚拟代理)和 Adapter 模式)提供了替代的动态机制。虽然这些模式不使用动态代理,只用普通的类就能够实现,但是在许多情况下,动态代理方式更方便、更紧凑,可以清除许多手写或生成的类。
7 E3 L1 ?" ^2 [Proxy模式6 A+ E( _7 }2 N3 D# Q" i
Proxy 模式中要创建“stub”或“surrogate”对象,它们的目的是接受请求并把请求转发到实际执行工作的其他对象。远程方法调用(RMI)利用 Proxy 模式,使得在其他 JVM 中执行的对象就像本地对象一样;企业 JavaBeans (EJB)利用 Proxy 模式添加远程调用、安全性和事务分界;而 JAX-RPC Web 服务则用 Proxy 模式让远程服务表现得像本地对象一样。在每一种情况中,潜在的远程对象的行为是由接口定义的,而接口本质上接受多种实现。调用者(在大多数情况下)不能区分出它们只是持有一个对 stub 而不是实际对象的引用,因为二者实现了相同的接口;stub 的工作是查找实际的对象、封送参数、把参数发送给实际对象、解除封送返回值、把返回值返回给调用者。代理可以用来提供远程控制(就像在 RMI、EJB 和 JAX-RPC 中那样),用安全性策略包装对象(EJB)、为昂贵的对象(EJB 实体 Bean)提供惰性装入,或者添加检测工具(例如日志记录)。
0 T. J' g2 H' U" a在 5.0 以前的 JDK 中,RMI stub(以及它对等的 skeleton)是在编译时由 RMI 编译器(rmic)生成的类,RMI 编译器是 JDK 工具集的一部分。对于每个远程接口,都会生成一个 stub(代理)类,它代表远程对象,还生成一个 skeleton 对象,它在远程 JVM 中做与 stub 相反的工作 —— 解除封送参数并调用实际的对象。类似地,用于 Web 服务的 JAX-RPC 工具也为远程 Web 服务生成代理类,从而使远程 Web 服务看起来就像本地对象一样。% P. }1 y" R' o- {# u8 `+ B
不管 stub 类是以源代码还是以字节码生成的,代码生成仍然会向编译过程添加一些额外步骤,而且因为命名相似的类的泛滥,会带来意义模糊的可能性。另一方面,动态代理机制支持在编译时没有生成 stub 类的情况下,在运行时创建代理对象。在 JDK 5.0 及以后版本中,RMI 工具使用动态代理代替了生成的 stub,结果 RMI 变得更容易使用。许多 J2EE 容器也使用动态代理来实现 EJB。EJB 技术严重地依靠使用拦截(interception)来实现安全性和事务分界;动态代理为接口上调用的所有方法提供了集中的控制流程路径。! U3 ?; u3 l# _: F* W! f4 Z) |
动态代理机制1 x. S* H( ~+ `! z% ^
动态代理机制的核心是 InvocationHandler 接口,如清单 1 所示。调用句柄的工作是代表动态代理实际执行所请求的方法调用。传递给调用句柄一个 Method 对象(从 java.lang.reflect 包),参数列表则传递给方法;在最简单的情况下,可能仅仅是调用反射性的方法 Method.invoke() 并返回结果。
8 @/ k/ S: E) ^7 w1 M8 K清单 1. InvocationHandler 接口" @' M8 z7 w, f" H; U- p
public interface InvocationHandler { Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }
9 u, A/ e7 s* G% U% A每个代理都有一个与之关联的调用句柄,只要代理的方法被调用时就会调用该句柄。根据通用的设计原则:接口定义类型、类定义实现,代理对象可以实现一个或多个接口,但是不能实现类。因为代理类没有可以访问的名称,它们不能有构造函数,所以它们必须由工厂创建。清单 2 显示了动态代理的最简单的可能实现,它实现 Set 接口并把所有 Set 方法(以及所有 Object 方法)分派给封装的 Set 实例。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-5-13 09:36 , Processed in 0.203102 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表