Java的代理机制

使用代理 Proxzy 可以在运行时创建一组给定接口的新类,这种功能只有在编译时无法确定需要实现哪种接口时才需要使用。

1. 使用代理的时机

假如有一个表示接口的 Class 对象,它的确切类型在编译时无法得知。由于没有实现类而只有一个接口,反射和newInstance语句是无法实例化这个 Class 对象的,我们需要在程序处于运行状态时定义一个新类。

代理类可以在运行时创建全新的类,这样的代理类可以实现指定的接口,它具有下列方法:

  • 指定接口所需要的全部方法。
  • Object 类中的全部方法,例如toString()equals()等。

在代理机制中,不能再允许时定义这些方法的新代码,而是要提供一个调用处理器 InvocationHandler调用处理器是实现了InvocationHandler接口的类对象。在这个接口中只有一个方法:

Object invoke(Object proxy, Method method, Object[] args)

无论何时调用代理对象的方法,invoke()方法都被调用,并向其传递 Method 对象和原始的调用参数,调用处理器必须给出处理调用的方式。

2. 创建代理对象

创建代理对象要使用 Proxy 类的newProxyInstance方法,这个方法有三个参数:

  • 一个类加载器。可以使用不同的类加载器,用 null 表示使用默认的类加载器。
  • 一个 Class 对象数组。每个元素都是需要实现的接口。
  • 一个调用处理器。

下面给出一个示例程序,使用代理和调用处理跟踪方法调用:

// 调用处理器
class TraceHandler implements InvocationHandler{
private Object target; // 构造函数
public TraceHandler(Object t){
target = t;
} // invoke方法
public Object invoke(Objcet proxy, Method m, Object[] args) throws Throwable {
// print method name and parameters
...
// invoke actual method
return m.invoke(target, args);
}
}

下面的代码,我们用于跟踪方法调用的代理对象:

Object value = ...;
// 构造调用处理器
InvocationHandler handler = new TraceHandler(value);
// 构造代理对象
Class[] interfaces = new Class[](Comparable.class);
Object proxy = Proxy.newProxyInstance(null, interfaces, handler);

我们再用 proxy 任何方法时,都会调用invoke()方法,打印出方法的名字和参数,再用value对象调用它。

3. 代理类的特性

代理类有下面这样一些特性:

  • 所有的代理类都扩展于 Proxy 类。一个代理类只有一个实例域:调用处理器。
  • 所需的任何附加数据存储在调用处理器中,例如代理 Comparable 对象时,在TraceHandler 中包装了实际的对象target
  • 所有的代理类都覆盖了 Object 类中的方法toString()equals()hashCode()。如果所有的代理方法一样,这些方法仅仅调用了调用处理器的invoke()。Object 类中的其他方法没有被重新定义。
  • 对于特定的类加载器和一组预设的接口,最多只能有一个代理类。也就是说如果用同样的参数重复调用两次newProxyInstance()方法,那么只能得到一个类的两个对象。
  • 代理类一定是 public、final 。如果代理类实现的所有接口都是 public 的,代理类就不属于某个特定的包。否则所有非公有的接口必须属于同一个包,代理类也属于这个包。
  • 可以用 Proxy 类的isProxyClass()方法检测一个特定的 Class 对象是否是一个代理类。

Java的代理机制的更多相关文章

  1. Java 动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  2. 学习AOP之JAVA的代理机制

    从一个输出日志的实例分析JAVA的代理机制 一.通用的日志输出方法  :需要在每个类里都增加对输出日志信息的代码 二.通过面向接口编程实现日志的输出(JAVA的静态代理):虽然实现了业务逻辑与输出日志 ...

  3. Java 动态代理机制分析及扩展

    Java 动态代理机制分析及扩展,第 1 部分 王 忠平, 软件工程师, IBM 何 平, 软件工程师, IBM 简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟 ...

  4. [转]Java 动态代理机制分析及扩展

    引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执 ...

  5. java动态代理机制

    首先了解代理设计模式,其思想是为其他对象提供一种代理以控制对这个对象的访问. java动态代理就是遵循这种思想,spring中的AOP实现原理就是java的动态代理. 在java的动态代理机制中,有两 ...

  6. Java 动态代理机制分析及扩展--转

    http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/#icomments http://www.ibm.com/developerworks/c ...

  7. Java 动态代理机制分析及扩展,第 1 部分

    Java 动态代理机制分析及扩展,第 1 部分 http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/ 本文通过分析 Java 动态代理的机制和特 ...

  8. 详解java动态代理机制以及使用场景

    详解java动态代理机制以及使用场景 https://blog.csdn.net/u011784767/article/details/78281384 深入理解java动态代理的实现机制 https ...

  9. 大厂高级工程师面试必问系列:Java动态代理机制和实现原理详解

    代理模式 Java动态代理运用了设计模式中常用的代理模式 代理模式: 目的就是为其他对象提供一个代理用来控制对某个真实对象的访问 代理类的作用: 为委托类预处理消息 过滤消息并转发消息 进行消息被委托 ...

随机推荐

  1. hdu-5587 Array(递归)

    Array Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Sub ...

  2. XSLT映射文件函数

    任何的编程语言或者是SQL语句都有内置的函数或方法,而强大灵活的xslt技术也是如此.熟练掌握XSLT的常用函数的用法,XSLT的应用将变得如此轻松,你会发现XSLT比想象中还要牛!以下是xslt数值 ...

  3. 玩转 ByteBuffer

    为什么要讲 Buffer 首先为什么一个小小的 Buffer 我们需要单独拎出来聊?或者说,Buffer 具体是在哪些地方被用到的呢? 例如,我们从磁盘上读取一个文件,并不是直接就从磁盘加载到内存中, ...

  4. Feign动态调用,结合Ribbon

    代码如下,三种方法: import org.springframework.beans.factory.annotation.Autowired;import org.springframework. ...

  5. 解决vue生产环境app.js或vendor文件过大问题

    1.去掉多余的库 将不必要的库卸载掉 npm uninstall xxx 举个例子:例如moment库文件是很大的,在前端可以用js的 new Date实现获取日期,或者可以其他库代替,也可以将mom ...

  6. Capstone CS5265规格书|CS5265参数|TYPEC转HDMI音视频转换拓展坞芯片

    一.CS5265总概 Capstone CS5265 USB Type-C到HDMI转换器结合了USB Type-C输入接口和数字高清多媒体接口(HDMI)输出.嵌入式微控制器(MCU)基于工业标准8 ...

  7. <数据结构>XDOJ332.二叉排序树的判定

    问题与解答 问题描述 给定一个二叉树,判断其是否是一个有效的二叉排序树. 假设一个二叉排序树具有如下特征: 结点的左子树只包含小于当前结点的树. 结点的右子树只包含大于当前结点的树. 所有左子树和右子 ...

  8. 使用.NET 6开发TodoList应用(15)——实现查询搜索

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 本文我们继续来看查询过程中的另外一个需求:搜索.搜索的含义是目标字段的全部或者部分值匹配请求中的搜索条件,对应到数据库层面是C ...

  9. Java EE数据持久化框架作业目录(作业笔记)

    第1章 MyBatis入门>>> 1.1.4 在Eclipse中搭建MyBatis基本开发环境 1.2.5 使用MyBatis查询所有职员信息 1.3.3 获取id值为1的角色信息. ...

  10. 加深理解Java异常概念并熟记5个最常见的运行时异常

    加深理解Java异常概念并熟记5个最常见的运行时异常 说明Error与Exception的联系和区别有哪些? 列举最常见的5个运用时异常. 1.Error和Exception的联系和区别: Error ...