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
随机推荐
- MINA系列学习-IoBuffer
在阅读IoBuffer源码之前,我们先看Mina对IoBuffer的描述:A byte buffer used by MINA applications. This is a replacement ...
- 接入百度语音SDK的步骤
1.导入依赖库 SystemConfiguration.framework AudioToolbox.framework UIkit.framework AVFoundation.framework ...
- iOS相册中图片按照时间排序
ios相册默认是按照时间从过去到现在排列,图片顺序有正序和逆序,group可以用以下方法来选择顺序 /** @param NSIndexSet 需要获取的相册中图片范围 @param NSEnumer ...
- 全栈开发必备的10款Sublime Text 插件
Sublime Text 具有漂亮的用户界面和强大的功能,例如代码缩略图,多重选择,快捷命令等.Sublime Text 更妙的是它的可扩展性.所以,这里挑选了全栈开发必备的10款 Sublime T ...
- MacDev.Mach-O.Programming-Part-III:MachOView-v2.4.9200.dmg-crash
MachOView-v2.4.9200.dmg Crash 在OS X(其版本号: 10.11.6 (15G31))下载MachOView-2.4.9200.dmg后,打开Fat Binary后,Ma ...
- Ext.Net TreePanel 修改Icon图标
分类: Ext.Net2012-09-24 13:44 1779人阅读 评论(0) 收藏 举报 webformserverextassemblyxhtmlobject 1.默认icon 2.自定义ic ...
- postgresql数据迁移
postgresql从库故障准备新库 1,创建用户[root@localhost home]# userdel postgres[root@localhost home]# groupdel post ...
- 【安卓安全】ARM平台代码保护之虚拟化
简介:代码的虚拟化即不直接通过CPU而是通过虚拟机来执行虚拟指令.代码虚拟化能有效防止逆向分析,可大大地增加了代码分析的难度和所需要的时间,若配合混淆等手段,对于动静态分析有着较强的防御能力. 背景: ...
- vpython初探
vpython 是python默认的3D模块,和python有一样的风格.与PyOpenGL相比,容易上手. vpython下载:vpython的官网(www.vpython.org).顺便说一句,官 ...
- 多层嵌套ajax同步
方式一: $.ajax({ type : "post", url : "user/add", data : data, async : false, //必须为 ...