java代理模式实例讲解
下面这个是设计模式课上的例子:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Vector; public class VectorProxy implements InvocationHandler { private Object targetObj; public Object getObject(){
return targetObj;
} public VectorProxy(Object Obj){
targetObj = Obj;
} public static Object factorary(Object Obj){ Class cla = Obj.getClass();
Object proxy = Proxy.newProxyInstance(cla.getClassLoader(), cla.getInterfaces(), new VectorProxy(Obj));
return proxy;
} public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("befor invoke "+method.getName());
if(args!=null){
for(Object o:args){
System.out.println(o.toString());
}
} Object tarObj = ((VectorProxy)(Proxy.getInvocationHandler(proxy))).getObject(); System.out.println(tarObj==targetObj); Object resultObj = method.invoke(targetObj,args); return resultObj;
} public static void main(String args[]){
List v = null;
v = (List)factorary(new Vector());
v.add("NEW");
System.out.println(v.get());
} }
结果:
befor invoke add
NEW
true
befor invoke get true
NEW
我通过这个例子来讲一下我对动态代理的理解。
从main函数入口开始。当我执行了v = (List)factorary(new Vector(10));的时候,这时所做的操作有21~24,我们看23行,这个Proxy.newProxyInstance函数会生成一个代理的实例,但是生成谁的实例呢?我们来看一下这个函数的原型:public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
它生成的是接口InvocationHandler这个接口的实例,在本例中中类VectorProxy实现了这个接口且在23行,传入将这个类传入进去了。这个函数返回实现了被代理类所实现的所有接口的Object对象,即动态代理,需要强制转型。代码中红色标注部分就是因为

Vector对应的接口是List,这里的返回值必须是接口。VectorProxy 中的子类必须是implements这个接口的类。
这里可以再看一下47行,对应于这句话(List)就是强制类型转换,类成员变量targetObj就是被代理类,这里是Vector,实现的所有接口则就是Vector的各种操作例如get,add这些。在47行,这个实现了所有Vector接口的Vector对象被赋值给了v。下面就是接口InvocationHandler里的这个invoke函数了,这个函数是自动调用的,29~39都是可以去掉的,有用的只是40行的这个。然后至于40行的这个详细内容可以去我的上篇博客 反射机制的进一步理解 中去看,这里不再赘述。
接下来看一下29~39行的这些对应的输出。这些输出的原理看完反射机制的进一步理解 之后都可以看懂,我就来讲一下37行的这句,先看一下Proxy这个类的成员变量:

如果你在factorary中加上一句 System.out.println("proxy的类型"+proxy.getClass().getName()); 然后对应的输出就是 proxy 的类型 $Proxy0,在 Proxy 的类的定义中我们发现它有一个 proxyClassNamePrefix 的东西,这个前缀加上0就是我们这个生成的代理的proxy,所以37行的那个 Object tarObj = ((VectorProxy)(Proxy.getInvocationHandler(proxy))).getObject(); 这儿proxy就是一个标号,然后其实就是那个v就是通过这个标号去进行add,get操作其实v(也就是proxy,接下来用v)并没有实现所有的方法,它只是通过invoke把v的这些操作通过java底层第调用仍然由被代理对象本身的函数去处理了,v所指代的并不是一个新的和之前的targetObj不一样的类,它只是一个指向了那个类的高级标识符,可以对类进行操作而已。合理猜测:Proxy中的两个map成员变量应该是存储多个代理类用的用来存放v(proxy)用的。讲到了这儿已经没有什么可再说的啦。
java代理模式实例讲解的更多相关文章
- 浅谈java代理模式
讲解java代理模式 目录 讲解java代理模式 何谓代理模式 静态代理 动态代理 JDK动态代理 CGLIB动态代理 何谓代理模式 代理模式,即Proxy Pattern,23种java常用设计模式 ...
- Java代理模式
java代理模式及动态代理类 1. 代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目 ...
- Java 代理模式(二) Java中的动态代理
动态代理类 Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类: 1.Interface InvocationHandler 该接口中仅定义了一个方法: Objec ...
- java 代理模式 总结
1.前言 最近舍友去面试遇到了关于java代理模式的问题. 我虽然知道怎么使用,但是没有做过正经的总结,因此有了这篇随笔,好好总结一下三大代理模式底层原理. 事实上,在开发项目的时候,基本用不上代理, ...
- Java代理模式示例程序
Java代理模式示例程序 当然不是我想出来的,是我看的一个网上教程里的. 模拟的是一个对电脑公司的代理 真实类的接口: public interface SaleComputer { public S ...
- Java代理模式/静态代理/动态代理
代理模式:即Proxy Pattern,常用的设计模式之一.代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问. 代理概念 :为某个对象提供一个代理,以控制对这个对象的访问. 代理类和委 ...
- JAVA代理模式与动态代理模式
1.代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用.代理模式给某 ...
- java 代理模式一: 静态代理
代理模式: 代理模式的作用:为其他对象提供一种代理以控制对 特定对象 的访问. 某种情况下,一个客户不想或者直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用:通过代理对象引用. ...
- JAVA 代理模式(Proxy)
1.代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 代理模式一般涉 ...
随机推荐
- php处理redis
1,connect 描述:实例连接到一个Redis.参数:host: string,port: int返回值:BOOL 成功返回:TRUE;失败返回:FALSE 示例: 1 2 3 4 5 <? ...
- thinkphp <volist>标签中 <if> 判断的写法
thinkphp <volist>标签中 <if> 判断的写法 <volist name="data" id="vo"> & ...
- 深入解析array_merge函数的用法 php (转)
array_merge是我们用来合并数组使用最多的函数: 下面就来深入解析array_merge的用法: 第四点是个坑需注意: 1:如果数组中有相同的字符串键名: 则该键名后面的值覆盖前面的值: 如果 ...
- 蓝桥杯 算法训练 ALGO-151 6-2递归求二进制表示位数
算法训练 6-2递归求二进制表示位数 时间限制:10.0s 内存限制:256.0MB 问题描述 给定一个十进制整数,返回其对应的二进制数的位数.例如,输入十进制数9,其对应的二进制数是1001 ...
- 让32位应用程序不再为2G内存限制苦恼
最近在做个程序,虽然是小型程序,但是使用的内存量却很大,动辄达到10G.在64位系统上可以轻松实现,无奈我是基于32位的系统进行开发,程序还没跑起来就已经被终止了. 试过很多办法,包括文件内 ...
- Python:常用正则表达式(一)
文章转载于:http://www.cnblogs.com/Akeke/(博主:Akeke) https://www.cnblogs.com/Akeke/p/6649589.html (基于JavaSc ...
- MySQL 数据库 练习题
一.表关系 请创建如下表,并创建相关约束 二.操作表 1.自行创建测试数据 2.查询“生物”课程比“物理”课程成绩高的所有学生的学号: 3.查询平均成绩大于60分的同学的学号和平均成绩: 4.查询所有 ...
- C# Remoting 简单实现
此处下载源代码(VS2010编译通过) http://files.cnblogs.com/files/qqhfeng/%E8%BF%9C%E7%A8%8B%E8%B0%83%E7%94%A8%E6 ...
- springJunit测试
; m.setModelType(s); m.setModelUrlType(s); modelService.create(m); } } 来源: http://enki-ding-yeah-n ...
- JAVA基础知识总结5(面向对象特征之一:继承)
继 承: 1:提高了代码的复用性. 2:让类与类之间产生了关系,提供了另一个特征多态的前提. 父类的由来:其实是由多个类不断向上抽取共性内容而来的. JAVA只支持单继承.java虽然不直接支持多继承 ...