java-代理模式及动态代理
代理模式
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在考虑到性能或安全等因素的情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
Proxy代理类:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
Target目标类:代理角色所代表的真实对象,是我们最终要引用的对象。
动态代理
假如要按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。但是实际使用时,一个真实角色对应一个代理角色,假如大量使用会导致类的急剧膨胀;此外,假如事先并不知道真实角色,该如何使用代理呢?这个问题可以通过Java的动态代理类来解决。
java动态类的实现主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。
Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现。
Proxy
提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
static InvocationHandler |
getInvocationHandler(Object proxy) 返回指定代理实例的调用处理程序。 |
static Class<?> |
getProxyClass(ClassLoader loader, Class<?>... interfaces) 返回代理类的 java.lang.Class 对象,并向其提供类加载器和接口数组。 |
static boolean |
isProxyClass(Class<?> cl) 当且仅当指定的类通过 getProxyClass 方法或newProxyInstance 方法动态生成为代理类时,返回 true。 |
static Object |
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。 |
- 参数:
loader
- 定义代理类的类加载器interfaces
- 代理类要实现的接口列表h
- 指派方法调用的调用处理程序
InvocationHandler
是代理实例的调用处理程序实现的接口。每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke
方法。
Object |
invoke(Object proxy, Method method, Object[] args) 在代理实例上处理方法调用并返回结果。 |
Object proxy:指被代理的对象。
Method method:要调用的方法
Object[] args:方法调用时所需要的参数
根据自己理解画的动态代理原理图
示例代码
写一个动态代理,其内部可以实现 ArrayList 和HashMap中完全相同的功能,并可以计算每个方法运行的时间。
定义代理工具类,可以根据目标和建议的不同生成不同的代理类对象。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
public class ProxyUtil {
//抽取方法,接收不同的目标和建议,返回一个代理
public static Object getProxy(final Object target,final Advice advice) {
/*参数:
定义代理类的类加载器
代理类要实现的接口列表
指派方法调用的调用处理程序*/
Object proxy = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler(){ public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
advice.beforeMethod(method);
Object retVal = method.invoke(target, args);
advice.afterMethod(method);
return retVal;
}
}
);
return proxy;
}
}
定义建议接口
import java.lang.reflect.Method;
public interface Advice {
void beforeMethod(Method method);
void afterMethod(Method method);
}
自定义建议类实现建议接口
import java.lang.reflect.Method;
public class MyAdvice implements Advice {
long beginTime = 0;
public void afterMethod(Method method) {
long endTime = System.currentTimeMillis();
System.out.println("["+method.getName() + "]耗时" + (endTime - beginTime)+"毫秒");
}
public void beforeMethod(Method method) {
beginTime = System.currentTimeMillis();
}
}
客户端测试
import java.util.*;
class TargetDemo
{
public static void main(String[] args)
{
//定义target
List<String> target = new ArrayList<String>();
//获取target的代理类对象
List proxy = (List)ProxyUtil.getProxy(target,new MyAdvice());
//代理类对象实现添加等方法
proxy.add("hello");
proxy.add("hehe");
proxy.add("hello");
System.out.println("size="+proxy.size());
for(Object tar : proxy){
System.out.println(tar);
} System.out.println("================"); Map<String,Integer> target1 = new HashMap<String,Integer>();
Map proxy1 = (Map)ProxyUtil.getProxy(target1,new MyAdvice());
proxy1.put("zhangsan1",21);
proxy1.put("zhangsan2",22);
proxy1.put("zhangsan2",22);
System.out.println("size="+proxy1.size());
Set<Map.Entry<String,Integer>> entrySet = proxy1.entrySet(); Iterator<Map.Entry<String,Integer>> it = entrySet.iterator(); while(it.hasNext())
{
Map.Entry<String,Integer> me = it.next();
String key = me.getKey();
Integer value = me.getValue(); System.out.println(key+"="+value);
}
}
}
运行结果:
---------- 运行 ----------
[add]耗时1毫秒
[add]耗时0毫秒
[add]耗时0毫秒
[size]耗时0毫秒
size=3
[iterator]耗时1毫秒
hello
hehe
hello
================
[put]耗时0毫秒
[put]耗时0毫秒
[put]耗时0毫秒
[size]耗时0毫秒
size=2
[entrySet]耗时0毫秒
zhangsan1=21
zhangsan2=22
输出完成 (耗时 0 秒) - 正常终止
java-代理模式及动态代理的更多相关文章
- (转)轻松学,Java 中的代理模式及动态代理
背景:讲到反射机制,肯定会想到动态代理. 轻松学,Java 中的代理模式及动态代理 代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强.值得注意的是,代理类和被代理类应该 ...
- Java设计模式-代理模式之动态代理(附源代码分析)
Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代 ...
- Java代理模式之动态代理
动态代理类的源码是程序在运行期间由JVM根据反射等机制动态生成的,所以不存在代理类的字节码文件.代理角色和真实角色的联系在程序运行时确定! Java中有两种动态代理,一种是JDK自带的,另一种的CGL ...
- JAVA代理模式与动态代理模式
1.代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用.代理模式给某 ...
- Java的三种代理模式(Spring动态代理对象)
Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...
- java代理模式及动态代理类
1. 代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用 ...
- 代理模式-jdk动态代理
IDB package com.bjpowernode.proxy; /** * 代理类和目标类都必须使用同一个接口. */ public interface IDB { int insert(); ...
- 动态代理模式——JDK动态代理
今天,我就来讲一下动态代理的设计模式. 动态代理的意义在于生成一个代理对象,来代理真实对象,从而控制真实对象的访问.操作动态代理需要两个步骤:一.代理对象和真实对象建立代理关系.二.实现代理对象的代理 ...
- 代理模式与动态代理之JDK实现和CGlib实现
静态代理 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类. 由业务实现类.业务代理类 两部分组成.业务实现类 负责实现主要的业务方法,业务代理类负责对调用的业务方法作拦截.过滤.预处理, ...
- Java 中的代理模式及动态代理
原文:https://blog.csdn.net/briblue/article/details/73928350
随机推荐
- JS valueOf与字符串
js在处理字符串和数值加运算的时候会转换数值为字符串 然后执行字符串连接 在覆盖String.prototype.valueOf之前,new String(111)这样的字符串与数值加法也是字符串连接 ...
- linux提取指定字符的行列并生成新文件(awk命令)
如图所示,命名为file文件的表头有BP.A1.TEST等 假如想提取含有"ADD"的行和该行对应列的"BP"和"P"值,则需要用到以下命令 ...
- 第二章 centos安装maven
一.官网下载 apache-maven-3.3.9-bin.tar.gz 注意:需要jdk1.7及以上 二.上传 scp apache-maven-3.3.9-bin.tar.gz root@10.2 ...
- js闭包使用
闭包就是在一个函数内定义一个内部函数 并返回内部函数 function f1(){ var a=1; add=function(){a=a+1;} function f1Sub(){ console. ...
- hihoCoder 1309:任务分配 贪心 优先队列
#1309 : 任务分配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定 N 项任务的起至时间( S1, E1 ), ( S2, E2 ), ..., ( SN, ...
- 在Linux上配置xampp后远程访问域名报错
在Linux上配置xampp后远程访问域名报错: New XAMPP security concept: Access to the requested object is only availabl ...
- .NET entityframework for mysql ,datetime字段存储值时有误差
昨天Tester发现数据有问题,大部分时间“datetime类型”都多了一秒,很少一部分数据的时间能完全对上(年月日时分秒),因为缺少关键日志,就各种排查,最后发现在调用Savechange方法前一刻 ...
- adv联系题
http://www.cnblogs.com/kuangbin/archive/2011/07/29/2120667.html(新)
- hibernate常用关联
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns=" ...
- 蓝牙BLE实用教程
蓝牙BLE实用教程 Bluetooth BLE 欢迎使用 小书匠(xiaoshujiang)编辑器,您可以通过 设置 里的修改模板来改变新建文章的内容. 1.蓝牙BLE常见问答 Q: Smart Re ...