Java代理类Proxy的用法
代理(proxy)
利用代理可以在运行时创建一个实现了一组给定接口的新类。这种功能只有在编译时无法确定需要实现哪个接口时才有必要使用。
何时使用代理
假设有一个表示接口的Class对象(有可能只包含一个接口),它的确切类型在编译时无法知道。要想构造一个实现这些接口的类,就需要使用newInstance方法或反射找出这个类的构造器。但是,不能实例化一个接口,需要在程序处于运行状态时定义一个新类。
代理类可以在运行时创建全新的类。这样的代理类能够实现指定的接口。尤其是,它具有下列方法:
- 指定接口所需要的全部方法
- Object类中的全部方法,例如, toString, equals等。
创建代理对象
要想创建一个代理对象,需要使用Proxy类的newProxyInstance方法。这个方法有三个参数:
- 一个类加载器(class loader)。
- 一个Class对象数组,每个元素都是需要实现的接口。
- 一个调用处理器
还有两个需要解决的问题。如何定义一个处理器?能够用结果代理对象做些什么?当然,这两个问题的答案取决于打算使用代理机制解决什么问题。比如
- 路由对远程服务器的方法调用
- 调试,跟踪
- log
Demo
我们定义一个处理器,用来打印调用的参数
public class TraceHandler implements InvocationHandler {
private Object target;
public TraceHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.print(target);
System.out.print("." + method.getName() + "(");
if (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(")");
return method.invoke(target, args);
}
}
接下来,我们用它来代理Comparable接口,看看怎么调用。比如Arrays的二分查找方法binarySearch
@Test
public void traceBinarySearch() {
Object[] elements = new Object[1000];
for (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;
}
Integer key = new Random().nextInt(elements.length) + 1;
int result = Arrays.binarySearch(elements, key);
if (result > 0) {
System.out.println(elements[result]);
}
}
控制台打印结果:
500.compareTo(94)
250.compareTo(94)
125.compareTo(94)
62.compareTo(94)
93.compareTo(94)
109.compareTo(94)
101.compareTo(94)
97.compareTo(94)
95.compareTo(94)
94.compareTo(94)
94.toString()
94
代理类的特性
- 代理类是在运行过程中创建的,创建完毕后和常规类相同,虚拟机同等对待。
- 所有的代理类都扩展于Proxy类。一个代理类只有一个实例域---调用处理器,它定义在Proxy的超类中。
- 没有定义代理类的名字,Sun虚拟机中的Proxy类将生成一个以字符串$Proxy开头的类名。
- 对于特定的类加载器和预设的一组接口来说,只能有一个代理类。也就是说,如果使用同一个类加载器和接口数组调用两次newProxyInstance方法的话,只能得到同一个类的两个对象。比如
class com.sun.proxy.$Proxy4
.可以使用getProxyClass
来获取这个类。 - 代理类一定是public final的。
- 可以通过
Proxy.isProxyClass
方法检测一个特定的Class对象是否代表一个代理类。
来源
- Java核心技术
Java代理类Proxy的用法的更多相关文章
- Java代理设计模式(Proxy)的四种具体实现:静态代理和动态代理
面试问题:Java里的代理设计模式(Proxy Design Pattern)一共有几种实现方式?这个题目很像孔乙己问"茴香豆的茴字有哪几种写法?" 所谓代理模式,是指客户端(Cl ...
- Java代理设计模式(Proxy)的几种具体实现
Proxy是一种结构设计模型,主要解决对象直接访问带来的问题,代理又分为静态代理和动态代理(JDK代理.CGLIB代理. 静态代理:又程序创建的代理类,或者特定的工具类,在平时开发中经常用到这种代理模 ...
- 深入解析OpenCart的代理类proxy
1.什么是代理类 代理类指的是连接远程对象或不可见对象的接口,通常被客户端调用来连接真实的服务对象.更准确的定义参见维基百科 2.代理的作用 作为一个包装类,提供额外的功能 延迟加载 在本文讲到的op ...
- java枚举类的常见用法
枚举类型(Enumerated Type) 很早就出现在编程语言中,它被用来将一组类似的值包含到一种类型当中.而这种枚举类型的名称则会被定义成独一无二的类型描述符,在这一点上和常量的定义相似.不过相比 ...
- java代理类及AOP
1.代理架构图 2.AOP 3.动态代理概念 4.动态代理工作原理图
- Java中的动态代理以及Proxy类的偷瞄
动态代理机制 所谓动态代理,即通过代理类Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. Java动态代理类位于Java.lang.reflect包 ...
- Java的动态代理(dynamic proxy)
什么是动态代理(dynamic proxy) 动态代理(以下称代理),利用Java的反射技术(Java Reflection),在运行时创建一个实现某些给定接口的新类(也称“动态代理类”)及其实例(对 ...
- 探索Mybatis之JDK动态代理:探究Proxy.newProxyInstance()生成的代理类解析
Mybatis的Mapper接口UserMapper 1 package com.safin.Mapper; 2 3 import com.safin.Pojo.User; 4 5 import ja ...
- java代理通俗简单解析
1 代理 1.1 代理的概念和作用 代理的概念很好理解,就像黄牛代替票务公司给你提供票,经纪人代理艺人和别人谈合作.Java的代理是指实现类作为代理类的属性对象, ...
随机推荐
- centos7之firewalld防火墙的配置与使用
firewalld是centos7开始提供的管理防火墙工具,提供了一个动态管理的防火墙,当然低层仍然调用的是 netfilter . 一.区域(zone)firewalld将网卡对应到不同的区域(zo ...
- python免密远程执行shell
使用paramiko库:https://github.com/paramiko/paramiko 简单封装SSH类 import paramiko class SSH: def __init__(se ...
- sql server pivot
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[YearSalary]( [year] [int] NULL, ...
- GitHub 2019年年度报告:Python最受欢迎,VScode贡献者高达19.1K
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 开源最前线(ID:OpenSourceTop) PS:如有需要Pyt ...
- Javase之多线程(1)
多线程(1) 多线程的概述 了解多线程之前需要先了解线程,而线程依赖于进程而存在,所以先了解进程. 什么是进程 进程就是正在运行的程序.是系统进行资源分配和调用的独立单位.每一个进程都有它自己的内存空 ...
- INSTALL_FAILED_TEST_ONLY
查看博客:http://www.enjoytoday.cn/posts/159 Android studio安装apk无法安装,报错误,网上搜索可以看到都说是:* 调用者不被允许测试的测试程序*,但具 ...
- PWA入门:手把手教你制作一个PWA应用
摘要: PWA图文教程 原文:PWA入门:手把手教你制作一个PWA应用 作者:MudOnTire Fundebug经授权转载,版权归原作者所有. 简介 Web前端的同学是否想过学习app开发,以弥补自 ...
- nginx在centos下的安装
第一步:打开浏览器下载,再上传到centOS系统中 http://nginx.org/download/ 或者在 centOS系统输入: wget http://nginx.org/download/ ...
- SQLyog使用期限(治标不治本的,治本的还没找到)
在注册表中找到 HKEY_CURRENT_USER\Software 选中其中的类似下列文件名的文件 HKEY_CURRENT_USER\Software\{d58cb4b1-47f3-45cb ...
- fiddler---Fiddler查看get和post请求
前几篇写了Fiddler的一些功能介绍,今天我们一起学习下如何通过fiddler查看get请求和post请求和get,post区别 get请求 1.启动fiddler,抓取安静博客地址 2.通过fid ...