Java的代理机制
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的代理机制的更多相关文章
- Java 动态代理机制详解
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- 学习AOP之JAVA的代理机制
从一个输出日志的实例分析JAVA的代理机制 一.通用的日志输出方法 :需要在每个类里都增加对输出日志信息的代码 二.通过面向接口编程实现日志的输出(JAVA的静态代理):虽然实现了业务逻辑与输出日志 ...
- Java 动态代理机制分析及扩展
Java 动态代理机制分析及扩展,第 1 部分 王 忠平, 软件工程师, IBM 何 平, 软件工程师, IBM 简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟 ...
- [转]Java 动态代理机制分析及扩展
引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执 ...
- java动态代理机制
首先了解代理设计模式,其思想是为其他对象提供一种代理以控制对这个对象的访问. java动态代理就是遵循这种思想,spring中的AOP实现原理就是java的动态代理. 在java的动态代理机制中,有两 ...
- Java 动态代理机制分析及扩展--转
http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/#icomments http://www.ibm.com/developerworks/c ...
- Java 动态代理机制分析及扩展,第 1 部分
Java 动态代理机制分析及扩展,第 1 部分 http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/ 本文通过分析 Java 动态代理的机制和特 ...
- 详解java动态代理机制以及使用场景
详解java动态代理机制以及使用场景 https://blog.csdn.net/u011784767/article/details/78281384 深入理解java动态代理的实现机制 https ...
- 大厂高级工程师面试必问系列:Java动态代理机制和实现原理详解
代理模式 Java动态代理运用了设计模式中常用的代理模式 代理模式: 目的就是为其他对象提供一个代理用来控制对某个真实对象的访问 代理类的作用: 为委托类预处理消息 过滤消息并转发消息 进行消息被委托 ...
随机推荐
- 1025 - The Specials Menu
1025 - The Specials Menu PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 ...
- 慢 SQL 优化
# 导致SQL执行慢的原因 1. 硬件问题.如网络速度慢,内存不足,I/O吞吐量小,磁盘空间满了等. 2. 没有索引或者索引失效.(一般在互联网公司,DBA会在半夜把表锁了,重新建立一遍索引,因为当你 ...
- Improved Variational Inference with Inverse Autoregressive Flow
目录 概 主要内容 代码 Kingma D., Salimans T., Jozefowicz R., Chen X., Sutskever I. and Welling M. Improved Va ...
- [opencv]求像素范围中最大值与最小值
double minv = 0.0, maxv = 0.0; double* minp = &minv; double* maxp = &maxv; minMaxIdx(channel ...
- Java初学者作业——定义一个计算器类, 实现计算器类中加、 减、 乘、 除的运算方法, 每个方法能够接收2个参数。
返回本章节 返回作业目录 需求说明: 定义一个计算器类, 实现计算器类中加. 减. 乘. 除的运算方法, 每个方法能够接收2个参数. 实现思路: 定义计算器类. 定义计算器类中加.减.乘.除的方法. ...
- 年功序列c++游戏
题目描述 在虚拟国度里多了很多 Virtual oier,为了树立对后辈的威信,从第 11 个 Virtual oier 开始的 oier 们搞起了年功序列的制度. 虚拟国度的创始人 oier Cht ...
- python 根据传进来的参数,动态拼接sql
根据传进来的参数,动态拼接sql,可用于实现一个方法,有些字段不确定,又用到的情况,如查询,三个查询条件,有的时候只用到一个查询条件,其他用不到则不需要拼接 def show_runjob_detai ...
- python + pymysql连接数据库报“(2003, "Can't connect to MySQL server on 'XXX数据库地址' (timed out)")”
python + pymysql连接数据库报"(2003, "Can't connect to MySQL server on 'XXX数据库地址' (timed out)&quo ...
- Pytest_fixture(9)
什么是fixture fixture是pytest特有的功能,使用装饰器 @pytest.fixture 标记的函数在其他函数中能被当作参数传入并被调用. fixture有明确的名字,在其他函数,模块 ...
- spring boot 使用 AOP 的正确姿势 --- 心得
1.前言 向spring boot转型,所有的配置基本上是用注解完成 ,以前使用spring MVC 需要写一大堆xml文件来配置. 基本上没什么变化,但是有些地方需要注意: 环绕通知不要使用异常捕获 ...