java代理的原理及应用
什么是代理模式?
定义
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
——百度百科
代理模式的角色
抽象角色:代理对象和真实对象的共同接口
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能够代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
示意图
代理模式的分类及使用
静态代理
![](/assets/blank.gif)
![](/assets/blank.gif)
1 package staticProxy; 2 3 // 抽象角色,真是对象与代理对象的共同接口 4 public interface Subject { 5 public void request(); 6 }
抽象角色
![](/assets/blank.gif)
![](/assets/blank.gif)
1 package staticProxy; 2 3 //代理对象,用来被客户端直接调用的类,内部被注入真实对象,可以在调用真是对象的方法前后做预处理和后处理 4 public class ProxyClass implements Subject { 5 6 Subject subject; 7 8 ProxyClass (Subject subject) { 9 this.subject = subject; 10 } 11 12 @Override 13 public void request() { 14 System.out.println("prefix-process!"); 15 subject.request(); 16 System.out.println("suffix-process!"); 17 } 18 19 }
代理角色
![](/assets/blank.gif)
![](/assets/blank.gif)
1 package staticProxy; 2 3 //真实对象,委托类 4 public class RealClass implements Subject { 5 6 @Override 7 public void request() { 8 System.out.println("I'm realClass!"); 9 } 10 11 }
真实角色
![](/assets/blank.gif)
![](/assets/blank.gif)
1 package staticProxy; 2 3 //客户端 4 public class StaticProxy { 5 public static void main(String[] args) { 6 Subject subject = new ProxyClass(new RealClass()); 7 8 subject.request(); 9 } 10 }
客户端
静态代理的缺点很显著,对每一个委托类都需要创建一个代理类,为了解决这个问题,java提供了动态代理。
动态代理
抽象角色与真实角色的定义和静态代理完全一致,这里不再重复定义
动态代理类需要继承自InvocationHandler接口,并实现其中的invoke方法。
![](/assets/blank.gif)
![](/assets/blank.gif)
1 package dynamicProxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 6 public class ProxyClass implements InvocationHandler { 7 8 Object subject; 9 10 public ProxyClass(Object subject) { 11 this.subject = subject; 12 } 13 14 @Override 15 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 16 System.out.println("prefix-process!"); 17 method.invoke(subject, args); 18 System.out.println("suffix-process!"); 19 return null; 20 } 21 22 }
动态代理类
![](/assets/blank.gif)
![](/assets/blank.gif)
1 package dynamicProxy; 2 3 import java.lang.reflect.Proxy; 4 5 public class DynamicProxy { 6 public static void main(String[] args) { 7 8 Subject subject = (Subject) Proxy.newProxyInstance(RealClass.class.getClassLoader(), 9 new Class[] {Subject.class}, new ProxyClass(new RealClass())); 10 11 subject.request(); 12 } 13 }
客户端
动态代理的实现原理
动态代理的实现主要依赖于java.lang.reflect.InvocationHandler接口与java.lang.reflect.Proxy类,其实现原理是基于java的反射技术。
InvocationHandler接口
动态代理类需要继承自InvocationHandler接口,此接口中只包含一个方法invoke方法,接口原型如下:
![](/assets/blank.gif)
![](/assets/blank.gif)
1 package java.lang.reflect; 2 3 public interface InvocationHandler { 4 5 /** 6 * proxy:代表代理对象本身,用于调用本代理对象的其他方法 7 * method:代表正在被调用的委托类的方法 8 * args:代表调用方法的参数 9 */ 10 public Object invoke(Object proxy, Method method, Object[] args) 11 throws Throwable; 12 }
InvocationHandler
Proxy类
Proxy类中定义了很多的方法,但根据上面动态代理的应用我们看到,最重要的一个方法就是newProxyInstance方法,该方法的作用就是动态创建一个代理类对象:
![](/assets/blank.gif)
![](/assets/blank.gif)
1 /** 2 * loader代表了委托类的类加载器 3 * interfaces代表了委托类的接口数组 4 * h代表委托类的实例 5 */ 6 @CallerSensitive 7 public static Object newProxyInstance(ClassLoader loader, 8 Class<?>[] interfaces, 9 InvocationHandler h) 10 throws IllegalArgumentException 11 { 12 // 判断委托类实例是否为空,如果未空抛异常 13 Objects.requireNonNull(h); 14 15 final Class<?>[] intfs = interfaces.clone(); 16 final SecurityManager sm = System.getSecurityManager(); 17 if (sm != null) { 18 checkProxyAccess(Reflection.getCallerClass(), loader, intfs); 19 } 20 21 /* 22 * 获取获取代理类的Class实例 23 */ 24 Class<?> cl = getProxyClass0(loader, intfs); 25 26 /* 27 * Invoke its constructor with the designated invocation handler. 28 */ 29 try { 30 if (sm != null) { 31 checkNewProxyPermission(Reflection.getCallerClass(), cl); 32 } 33 34 //获取代理类的Constructor对象 35 final Constructor<?> cons = cl.getConstructor(constructorParams); 36 final InvocationHandler ih = h; 37 if (!Modifier.isPublic(cl.getModifiers())) { 38 AccessController.doPrivileged(new PrivilegedAction<Void>() { 39 public Void run() { 40 cons.setAccessible(true); 41 return null; 42 } 43 }); 44 } 45 46 //利用反射原理中使用constructor动态创建动态代理类型 47 return cons.newInstance(new Object[]{h}); 48 } catch (IllegalAccessException|InstantiationException e) { 49 throw new InternalError(e.toString(), e); 50 } catch (InvocationTargetException e) { 51 Throwable t = e.getCause(); 52 if (t instanceof RuntimeException) { 53 throw (RuntimeException) t; 54 } else { 55 throw new InternalError(t.toString(), t); 56 } 57 } catch (NoSuchMethodException e) { 58 throw new InternalError(e.toString(), e); 59 } 60 }
newProxyInstance
动态代理的应用场景
动态代理最著名的应用场景就是spring中的aop
转载于:https://www.cnblogs.com/qq455988971/p/8242946.html
java代理的原理及应用相关推荐
- java高级----Java动态代理的原理
Java动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程 ...
- java代理的学习,通过类实现接口来实现代理。proxy来创建动态类,和InvocationHandler接口的实现,和工作原理。...
1.java自带的proxy类可以创建动态类,如果一个类实现了一个接口那么久可以为这个类创建代理. 2.代理:就是当用户要调用一个类的方法时,用户可以通过调用代理,代理通过接口调用原来的类的方法,代理 ...
- Java动态代理的原理
Java动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程 ...
- java 动态代理实现原理
上篇讲了:java动态代理浅析 这篇讲讲其内部实现原理. 1.相关的类和接口 1.1 java.lang.reflect.Proxy 这是 Java 动态代理机制的主类,它提供了一组静态方法来为一组 ...
- Android开发如何理解Java静态代理 动态代理及动态生成代理对象原理 看这篇就够了
动态代理与静态代理 前言 代理模式 静态代理 动态代理 JDK代理 动态生成代理对象原理 生成class数据源码 动态代理类真身 总结 前言 近期在研究Hook技术,需要用到动态代理,说到动态代理就会 ...
- Java 代理模式的实现和原理详细分析
文章目录 代理模式 静态代理 1. 静态代理的概念 2. 静态代理的实现 动态代理 1. 动态代理的概念 2. 动态代理的实现 2.1 如何创建一个动态代理对象 2.2 完整的动态代理的例子 3.动态 ...
- Spring 初识Aop JDK动态代理实现 原理初显
Spring 初识Aop JDK动态代理实现 原理初显 一.项目结构 二.具体步骤: 1.创建maven项目 创建好包结构 2.写一个TestDao接口 及实现类 3. 写一个自己的切面类 4.jav ...
- java代理通俗简单解析
1 代理 1.1 代理的概念和作用 代理的概念很好理解,就像黄牛代替票务公司给你提供票,经纪人代理艺人和别人谈合作.Java的代理是指实现类作为代理类的属性对象, ...
- Java代理模式——静态代理动态代理
proxy mode 1. 什么是代理 1.1 例子解释 1.2 作用 2. 静态代理 2.1 优缺点分析 2.2 以厂家卖u盘用代码说明 3. 动态代理 3.1 什么是动态代理 3.2 jdk实现原 ...
最新文章
- Quart 2D 绘制图形简单总结
- 解决Excel打开UTF-8编码的CSV文件乱码的问题 实测好用
- 利用反射自动封装成实体对象
- C++实现贪吃蛇(多线程,窗口设置,链表,音乐播放)
- : 字符向量未正常终止_文本挖掘从小白到精通(一)---语料、向量空间和模型的概念...
- Linux常见问题解答--如何修复“tar:Exiting with failure status due to previous errors”
- citp协议服务器,Picturall Octo 媒体服务器
- Windows 远程桌面连接命令
- 我那么爱你为什么?伤感爱情日志
- 文档安全有个服务器的组,云服务器安全组是什么意思
- 设备选型(选择交换机、选择路由器的技能指标)
- sdut 1309 不老的传说问题(区间DP,难,值得好好看)
- 关于南京市智慧教育基础平台市区协同推进项目申报工作的通知
- oracle数据库 uga,Oracle内存结构
- 太原理工大于丹计算机,陈永乐-太原理工大学信息与计算机学院
- 巴纳比·杰克和他发现的ATM取款和心脏起搏器漏洞
- 01 搭建一个Ubuntu 开发机
- 用 Python 爬取各类基金数据并动态展示
- 计算机毕业设计jsp小福星宠物领养管理系统
- MyBatis之association嵌套
热门文章
- PAT_B_1089_Java(20分)
- ddr读时序波形_测试新体验|如何解决DDR内存系统测试难题?
- 『设计模式』再谈Macdonald的汉堡口味--策略模式
- 使用Hadoop Streaming 完成MapReduce(Python代码)
- 【Ubuntu-Tensorflow】程序结束掉GPU显存没有释放的问题
- Struts2和Struts1.x的全面比较
- 信用卡消费退款,商家让客户付手续费,合理吗?
- “天下第一长联”与“元跨革囊”
- Deep Belief Networks
- 100g流量在电脑上可以用多久_三大运营商5G体验方案出炉!100G一个月够不够?...