• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Java > java 代理模式及动态代理机制深入分析

java 代理模式及动态代理机制深入分析

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了java动态代理模式,java23种设计模式,java单例模式,设计模式java,java设计模式有哪些等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

java 代理模式及动态代理机制深入分析

代理设计模式

       代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

代理模式一般涉及到的角色有:

抽象角色:声明真实对象和代理对象的共同接口;
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便

在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象

图 1. 代理模式类图


为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别。通过代理类这中间一层,能有效控制对委托 类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性。Java 动态代理机制以巧妙的方式近乎完美地实践了代理模式的设计理念。

java动态代理

相关的类和接口

要了解 Java 动态代理的机制,首先需要了解以下相关的类或接口:
· java.lang.reflect.Proxy:这是 Java 动态代理机制的主类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。

清单 1. Proxy 的静态方法 

// 方法 1: 该方法用于获取指定代理对象所关联的调用处理器 
 
static InvocationHandler getInvocationHandler(Object proxy)  
 
// 方法 2:该方法用于获取关联于指定类装载器和一组接口的动态代理类的类对象 
 
static Class getProxyClass(ClassLoader loader, Class[] interfaces)  
 
// 方法 3:该方法用于判断指定类对象是否是一个动态代理类 
 
static boolean isProxyClass(Class cl)  
 
// 方法 4:该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例 
 
static Object newProxyInstance(ClassLoader loader, Class[] interfaces,  
 
  InvocationHandler h)  
</div>

java.lang.reflect.InvocationHandler:这是调用处理器接口,它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。

清单 2. InvocationHandler 的核心方法

// 该方法负责集中处理动态代理类上的所有方法调用。第一个参数既是代理类实例,第二个参数是被调用的方法对象 
 
// 第三个方法是调用参数。调用处理器根据这三个参数进行预处理或分派到委托类实例上发射执行 
 
Object invoke(Object proxy, Method method, Object[] args)  
</div>

每次生成动态代理类对象时都需要指定一个实现了该接口的调用处理器对象(参见 Proxy 静态方法 4 的第三个参数)。
· java.lang.ClassLoader:这是类装载器类,负责将类的字节码装载到 Java 虚拟机(JVM)中并为其定义类对象,然后该类才能被使用。Proxy 静态方法生成动态代理类同样需要通过类装载器来进行装载才能使用,它与普通类的唯一区别就是其字节码是由 JVM 在运行时动态生成的而非预存在于任何个 .class 文件中。

每次生成动态代理类对象时都需要指定一个类装载器对象(参见 Proxy 静态方法 4 的第一个参数)

代理机制及其特点

首先让我们来了解一下如何使用 Java 动态代理。具体有如下四步骤:

1. 通过实现 InvocationHandler 接口创建自己的调用处理器;
2. 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
3. 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
4. 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。

清单 3. 动态代理对象创建过程

// InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发 
 
// 其内部通常包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用 
 
InvocationHandler handler = new InvocationHandlerImpl(..);  
 
 
// 通过 Proxy 为包括 Interface 接口在内的一组接口动态创建代理类的类对象 
 
Class clazz = Proxy.getProxyClass(classLoader, new Class[] { Interface.class, ... });  
 
 
// 通过反射从生成的类对象获得构造函数对象 
 
Constructor constructor = clazz.getConstructor(new Class[] { InvocationHandler.class });  
 
 
// 通过构造函数对象创建动态代理类实例 
 
Interface Proxy = (Interface)constructor.newInstance(new Object[] { handler });  
</div>

实际使用过程更加简单,因为 Proxy 的静态方法 newProxyInstance 已经为我们封装了步骤 2 到步骤 4 的过程,所以简化后的过程如

清单 4. 简化的动态代理对象创建过程

// InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发 
 
InvocationHandler handler = new InvocationHandlerImpl(..);  
 
// 通过 Proxy 直接创建动态代理类实例 
 
Interface proxy = (Interface)Proxy.newProxyInstance( classLoader,  
 
 new Class[] { Interface.class },  
 
 handler );  
</div>

下面我们来看一个简单实现动态代理的例子:

1.代理类和真实类接口:

public interface Subject 
 
{ 
 
public void request(); 
 
} 
</div>

2.真实类:

public class RealSubject implements Subject 
 
{ 
 
public void request() 
 
{ 
 
System.out.println("From real subject!"); 
 
}} 
</div>

3.具体代理类:

import java.lang.reflect.InvocationHandler; 
 
import java.lang.reflect.Method; 
 
public class DynamicSubject implements InvocationHandler 
 
{ 
 
private Object sub; 
 
public DynamicSubject(Object obj) 
 
{ 
 
this.sub = obj; 
 
} 
 
public Object invoke(Object proxy, Method method, Object[] args) 
 
throws Throwable 
 
{ 
 
System.out.println("before calling: " + method); 
 
method.invoke(sub, args);  
 
System.out.println(args == null);  
 
System.out.println("after calling: " + method); 
 
return null; 
 
} 
</div>

注:该代理类的内部属性是Object类型,实际使用的时候通过该类的构造方法传递进来一个对象。 此外,该类还实现了invoke方法,该方法中的method.invoke其实就是调用被代理对象的将要 执行的方法,方法参数是sub,表示该方法从属于sub,通过动态代理类,我们可以在执行真实对象的方法前后加入自己的一些额外方法。

4.客户端调用示例:

import java.lang.reflect.InvocationHandler; 
 
import java.lang.reflect.Proxy; 
 
public class Client 
 
{ 
 
public static void main(String[] args) 
 
{ 
 
RealSubject realSubject = new RealSubject(); 
 
InvocationHandler handler = new DynamicSubject(realSubject); 
 
Class<?> classType = handler.getClass(); 
 
// 下面的代码一次性生成代理 
 
Subject subject = (Subject) Proxy.newProxyInstance(classType 
 
.getClassLoader(), realSubject.getClass().getInterfaces(), 
 
handler); 
 
subject.request(); 
 
System.out.println(subject.getClass()); 
 
} 
 
} 
</div>

接下来让我们来了解一下 Java 动态代理机制 Proxy 的构造方法:

清单 6. Proxy 构造方法

// 由于 Proxy 内部从不直接调用构造函数,所以 private 类型意味着禁止任何调用 
 
private Proxy() {}  
 
 
// 由于 Proxy 内部



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Java动态代理分析及理解
  • Java代理模式详细解析
  • java 代理模式及动态代理机制深入分析
  • Java动态代理分析及理解

相关文章

  • 2017-05-28探索Java中的equals()和hashCode()方法_动力节点Java学院整理
  • 2017-05-28java用重定向方法从文件中读入或写入数据
  • 2017-05-28java后台利用Apache poi 生成excel文档提供前台下载示例
  • 2017-05-28spring+html5实现安全传输随机数字密码键盘
  • 2017-05-28Spring Boot 集成Dubbo框架实例
  • 2017-05-28Java中的几种读取properties配置文件的方式
  • 2017-05-28java 使用异常的好处总结
  • 2017-05-28Java通过PropertyDescriptor反射调用set和get方法
  • 2017-05-28Java this()和super()的使用注意
  • 2017-05-28Java正则表达式_动力节点Java学院整理

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Java微信公众平台开发(15) 微信JSSDK的使用
    • SpringMVC实现自定义类型转换器
    • Java interrupt()方法使用注意_动力节点Java学院整理
    • 简单实现Java验证码功能
    • spring boot中的静态资源加载处理方式
    • 详解SpringMVC注解版前台向后台传值的两种方式
    • 浅谈Java多线程实现及同步互斥通讯
    • java Future 接口使用方法详解
    • SWT(JFace) Wizard(Eclipse插件编程必备)
    • Java 多线程有序执行的几种方法总结

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有