浅谈java代理

【0】README

0.1) 本文描述+源代码均 转自 core java volume 1, 旨在理解 java代理机制 的基础知识;


【1】代理相关

1.1)利用代理可以在运行时创建一个实现了一组给定接口的新类, 这种功能只有在 编译时无法确定需要实现哪个接口时 才有必要使用;
1.2)假设有一个表示接口的 Class对象, 它的确切类型在编译时无法知道。 要想构造一个实现这些接口的类, 就需要使用 newInstance 方法或反射找出这个类的构造器;但是不能实例化一个接口, 需要在程序处于运行状态时定义一个新类;
1.3)解决问题的方法(代理机制): 代理机制是一种更好的解决方法。代理类可以在运行时创建全新的类, 这样代理类能够实现指定的接口,尤其是, 它具有以下方法:

  • 1.3.1)指定接口所需要的全部方法;
  • 1.3.2) Object 类中的全部方法, 例如 , toString, equals等;
  • 1.3.3)然而,不能在运行时定义这些方法的新代码。而是要提供一个 调用处理器(InvocationHandler), 该处理器是实现了 InvocationHandler 接口的类对象。在这个接口中只有一个方法: Object invoke(Object proxy, Method method, Object[] args) ; 要知道, 无论何时调用代理对象的方法, 调用处理器的invoke 方法都会被调用, 并向其传递Method对象和原始的调用参数;

1.4)要想创建一个代理对象, 需要使用Proxy类的 newProxyInstance 方法, 该方法有3个参数:

  • 1.4.1)一个类加载器:
  • 1.4.2)一个Class 对象数组: 每个元素都是需要实现的接口;
  • 1.4.3)一个调用处理器:
class TraceHandler implements InvocationHandlerInvocationHandler handler = new TraceHandler(value);
Object proxy = Proxy.newProxyInstance(null, new Class[] { Comparable.class } , handler);

1.5)但是,还有两个问题需要解决:
当然了,这两个问题的答案取决于打算使用代理机制解决什么问题。使用代理可能出于很多原因,如:

  • ex1)路由对远程服务费去的方法调用;
  • ex2)在程序运行期间, 将用户接口事件与动作关联起来;
  • ex3)为调试, 跟踪方法调用;

【2】看个荔枝(跟踪方法调用):

public class ProxyTest
{public static void main(String[] args){Object[] elements = new Object[1000];// fill elements with proxies for the integers 1 ... 1000for (int i = 0; i < elements.length; i++){Integer value = i + 1;InvocationHandler handler = new TraceHandler(value);Object proxy = Proxy.newProxyInstance(null, new Class[] { Comparable.class } , handler);elements[i] = proxy;}// construct a random integerInteger key = new Random().nextInt(elements.length) + 1;// search for the keyint result = Arrays.binarySearch(elements, key);// print match if foundif (result >= 0) System.out.println(elements[result]);}
}class TraceHandler implements InvocationHandler
{private Object target;public TraceHandler(Object t){target = t;}public Object invoke(Object proxy, Method m, Object[] args) throws Throwable{// print implicit argumentSystem.out.print(target);// print method nameSystem.out.print("." + m.getName() + "(");// print explicit argumentsif (args != null){for (int i = 0; i < args.length; i++){System.out.print(args[i]);if (i < args.length - 1) System.out.print(", ");}}System.out.println(")");// invoke actual methodreturn m.invoke(target, args);}
}

2.1)打印结果:
这里写图片描述

【2】代理类的特性

2.1)需要记住: 代理类是在程序运行过程中创建的, 然而, 一旦被创建, 就变成了常规类,与虚拟机中的任何其他类没有区别;
2.2)所有的代理类都扩展于 Proxy类。一个代理类只有一个实例域——调用处理器, 它定义在 Proxy的超类中, 为了履行代理对象的职责, 所需要的任何附加数据都必须存储在调用处理器中;
2.3)所有的代理类都覆盖了 Object类中的方法 toString、equals 和 hashCode 方法;这些方法仅仅 调用了 调用处理器 的invoke 方法;Object类中的其他方法没有被重新定义;
2.4)没有定义代理类的名字的话, Sun 虚拟机中的Proxy类将生成一个 以 字符串 $Proxy 开头的类名;
2.5)对于特定的类加载器和预设的一组接口来说, 只能有一个代理类;也就是说, 如果使用 同一个类加载器和接口数组调用两次 newProxyInstance 方法的话, 那么只能够得到同一个类的两个对象, 也可以利用 getProxyClass 方法获得这个类:

Class proxyClass = Proxy.getProxyClass(null,  interfaces);

2.6)代理类一定是 public 和 final, 如果代理类实现的所有接口都是 public, 代理类就不属于某个特定的包;否则,所有非公有的接口都必须属于同一个包;
2.7)可以调用 Proxy类中的 isProxyClass 方法 检测一个特定的 Class对象是否代表一个代理类;

[API] java.lang,reflect.InvocationHandler 1.3

Object invoke(Object proxy, Method method, Object[] args):返回实现指定接口的代理类;
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler handler) : 构造一个实现指定接口的代理类的实例, 所有方法都将调用给定处理器对象的invoke 方法;
static boolean isProxyClass(Class c) : 如果 c 是一个代理类返回 true

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331847.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

织梦mysql安装教程视频教程_织梦DedeCMSV6系统安装步骤教程

DedeCMSV6系统基于PHP7.*MySQL开发&#xff0c;本篇文档将介绍如何下载DedeCMSV6系统&#xff0c;并且通过之前已经部署好的系统环境来安装配置一个安全的站点。准备工作&#xff1a;主机一台(PHP7.0以上MYSQL)域名(做好解析绑定工作)源码下载通过DedeCMSV6系统下载页面可以获取…

无法创建t的通用数组_创建通用数组的问题

无法创建t的通用数组在这篇文章中&#xff0c;我们将介绍一篇全面的文章&#xff0c;其中介绍了创建通用数组的问题。 Java编程语言于2004年9月在Java 5.0“ Tiger”发行版中添加了泛型。 泛型或类型参数化系统在提供类型安全性的同时扩展了Java现有的类型系统。 1.简介 Java具…

贪婪算法+小应用(调度问题)

【0】README 0.1&#xff09; 本文总结于 数据结构与算法分析&#xff0c; 旨在 理解 “DFS应用——贪婪算法” 的idea&#xff1b; 【1】贪婪算法 1.1&#xff09;已经看到的三个贪婪算法&#xff1a; Dijkstra算、Prim算法 和 Kruskal 算法&#xff1b;&#xff08;Dijkstr…

http 安全性和幂等性_HTTP方法:幂等性和安全性

http 安全性和幂等性幂等性和安全性是HTTP方法的属性。 HTTP RFC定义了这些属性&#xff0c;并告诉我们哪些HTTP方法是安全且幂等的。 服务器应用程序应确保正确执行安全和幂等的语义&#xff0c;如客户端期望的那样。 安全的HTTP方法 如果HTTP方法不更改服务器状态&#xff0…

Huffman编码(Huffman树)

【0】README 0.1&#xff09; 本文总结于 数据结构与算法分析&#xff0c; 源代码均为原创&#xff0c; 旨在 理解 “Huffman编码&#xff08;Huffman树&#xff09;” 的idea 并用源代码加以实现&#xff1b; 0.2&#xff09; Huffman树的构建算法属于 贪婪算法&#xff0c;…

java获取文件列表_java获取指定目录中的文件列表

最近项目中会动态生成文件html及相关资源文件(css,js,png,mp3)&#xff0c;为了防止文件名重复&#xff0c;需要获取目录中相同类型文件的最大编号&#xff0c;下面我用代码来实现获得文件列表。public static void getFiles(String path) {File file new File(path);// 如果这…

jep290涉及jdk版本_针对JDK 14提议的另外六个JEP

jep290涉及jdk版本Mark Reinhold最近的消息宣布了六个新的“建议针对JDK 14的JEP ”&#xff1a; JEP 345 &#xff0c; JEP 361 &#xff0c; JEP 363 &#xff0c; JEP 364 &#xff0c; JEP 365和JEP 367 。 假设没有异议由11月7日提出&#xff0c;这些JEPs将有针对性地JDK …

近似装箱问题(三种联机算法实现)

【0】README 0.1&#xff09; 本文总结于 数据结构与算法分析&#xff0c; 源代码均为原创&#xff0c; 旨在 理解 “近似装箱问题&#xff08;三种联机算法实现&#xff09;” 的idea 并用源代码加以实现&#xff1b; 0.2&#xff09; 近似装箱问题的三种联机算法 分别是&am…

java 随机数种子_Java--随机数和随机数种子(转)

在计算机中并没有一个真正的随机数发生器&#xff0c;但是可以做到使产生的数字重复率很低&#xff0c;这样看起来好象是真正的随机数&#xff0c;实现这一功能的程序叫伪随机数发生器。有关如何产生随机数的理论有许多&#xff0c;如果要详细地讨论&#xff0c;需要厚厚的一本…

java 堆转储快照_捕获Java堆转储的7个选项

java 堆转储快照堆转储是诊断与内存相关的问题的重要工件&#xff0c;例如内存泄漏缓慢&#xff0c;垃圾回收问题和java.lang.OutOfMemoryError。它们也是优化内存消耗的重要工件。 有很棒的工具&#xff0c;例如Eclipse MAT和Heap Hero&#xff0c;可以分析堆转储。 但是&…

java 提取url参数_Java提取URL某个参数的值

ASP&period;NET Core 中文文档 第四章 MVC(4&period;3)过滤器原文:Filters 作者:Steve Smith 翻译:刘怡(AlexLEWIS) 校对:何镇汐 ASP.NET MVC 过滤器 可在执行管道的前后特定阶段执行代码.过滤器可以配置为全局有效.仅对控 ...jquery插件-表单提交插件-jQuery&peri…

近似装箱问题(两种脱机算法实现)

【0】README 0.1&#xff09; 本文总结于 数据结构与算法分析&#xff0c; 源代码均为原创&#xff0c; 旨在 理解 “近似装箱问题&#xff08;两种脱机算法实现&#xff09;” 的idea 并用源代码加以实现&#xff1b; 0.2&#xff09; 近似装箱问题的两种联机算法 分别是&am…

vaadin 10+_Vaadin 10+作为CUBA UI的未来

vaadin 10从一开始&#xff0c;Vaadin就成为CUBA平台用户界面的基石和重要组成部分。 凭借其创新的方法&#xff0c;它帮助CUBA将企业用户界面开发带到了一个非常有希望&#xff08;当今是默认&#xff09;的WEB领域。 Vaadin最令人兴奋的部分之一是整个开发都是同构的&#xf…

java 信息增益_对信息增益(IG,Information Gain)的理解和计算

可能理解的不对。决策树构建中节点的选择靠的就是信息增益了。信息增益是一种有效的特征选择方法&#xff0c;理解起来很简单&#xff1a;增益嘛&#xff0c;肯定是有无这个特征对分类问题的影响的大小&#xff0c;这个特征存在的话&#xff0c;会对分类系统带来多少信息量&…

使用文本编辑器和jdk_JDK 14:记录,文本块等

使用文本编辑器和jdk今天的Mark Reinhold帖子“ 建议JEP针对JDK 14&#xff1a;305、343、359、366和368 ”建议将另外五个JEP针对JDK 14 。 该组中有一些备受期待的功能&#xff0c;但建议将所有功能都“预览”或“孵化”&#xff1a; JEP 305 &#xff1a;instanceof的模式匹…

java compareable接口_Java对象比较-Comparable和Comparator接口使用

最近在学习贪心算法和动态规划的过程中&#xff0c;里面有一段自然排序的操作&#xff0c;顺便简单了解一下Java中对象比较后排序要使用的两个接口&#xff1a;Comparable和Comparator。如果是数字&#xff0c;直接比较就行&#xff0c;但是如果是对象&#xff0c;如何比较后排…

java初学者指南_Java代理初学者指南

java初学者指南尽管Java初学者很快学会了键入public static void main来运行他们的应用程序&#xff0c;但是即使是经验丰富的开发人员也常常不知道JVM对Java流程的两个附加入口点的支持&#xff1a; premain和agentmain方法。 这两种方法都允许所谓的Java代理在驻留在其自己的…

java txt html格式_java中xml(txt/html等格式)解析问题,请教java高手,请勿粘贴其他网页上的内容(能查的都看了)。...

目的&#xff1a;通过对网页内容解析&#xff0c;获得需要的内容&#xff0c;如网页的标题Title&#xff0c;主要内容&#xff0c;描述信息&#xff1b;而里面的广告、超链接、无关紧要的信息统统不要&#xff0c;从而达到对用户上网行为的分析的目的。下面是我...目的&#xf…

java泛型程序设计——定义简单泛型类+泛型方法

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java泛型程序设计 的 定义泛型类泛型方法的知识&#xff1b; 【1】一个泛型类&#xff1a; 就是具有一个或多个类型变量的类&#xff1b; 1.1&#xff09;看个荔枝&#xff1a; …

分布式 虚拟时间和虚拟同步_分布式虚拟跟踪

分布式 虚拟时间和虚拟同步跟踪提供了对系统的可见性&#xff0c;使开发人员和操作人员可以在运行时观察应用程序。 当系统不断增长并与更多微服务进行交互时&#xff0c;跟踪变得非常有价值。 在这样的环境中&#xff0c;这些痕迹非常棒&#xff0c;可以定位导致性能下降的故障…