Java实现动态代理

无边落木潇潇下 Java实现动态代理的大致步骤如下:

1.定义一个委托类和公共接口

1234567891011

//公共接口public interface IHello { void sayHello();}//委托类class Hello implements IHello { public void sayHello() { System.out.println("Hello world!!"); }}

2.通过实现InvocationHandler接口来自定义自己的InvocationHandler,指定运行时将生成的代理类需要完成的具体任务

1234567891011121314151617

//自定义InvocationHandlerpublic class HWInvocationHandler implements InvocationHandler { // 目标对象 private Object target; public HWInvocationHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) >throws Throwable { System.out.println("------插入前置通知代码-------------"); // 执行相应的目标方法 Object rs = method.invoke(target, args); System.out.println("------插入后置处理代码-------------"); return rs; }}

3.生成代理对象,这个可以分为四步: (1)通过Proxy.getProxyClass获得动态代理类 (2)通过反射机制获得代理类的构造方法,方法签名为getConstructor(InvocationHandler.class) (3)通过构造函数获得代理对象并将自定义的InvocationHandler实例对象传为参数传入 (4)通过代理对象调用目标方法

123456789101112131415

public class Client { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, >InvocationTargetException, InstantiationException { // 生成Proxy的class文件 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); // 获取动态代理类 Class<?> proxyClazz = Proxy.getProxyClass(IHello.class.getClassLoader(), IHello.class); // 获得代理类的构造函数,并传入参数类型InvocationHandler.class Constructor<?> constructor = proxyClazz.getConstructor(InvocationHandler.class); // 通过构造函数来创建动态代理对象,将自定义的InvocationHandler实例传入 IHello iHello = (IHello) constructor.newInstance(new HWInvocationHandler(new Hello())); // 通过代理对象调用目标方法 iHello.sayHello(); }}

Proxy类中还有个将2~4步骤封装好的简便方法来创建动态代理对象,其方法签名为:newProxyInstance(ClassLoader loader,Class<?>[] instance, InvocationHandler h),如下例:

12345678910

public class Client2 { public static void main(String[] args) throws NoSuchMethodException,IllegalAccessException, InvocationTargetException, InstantiationException { //生成$Proxy0的class文件 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); IHello ihello = (IHello) >Proxy.newProxyInstance(IHello.class.getClassLoader(), //加载接口的类加载器 new Class[]{IHello.class}, //一组接口 new HWInvocationHandler(new Hello())); //自定义的>InvocationHandler ihello.sayHello(); }}

这个静态函数的第一个参数是类加载器对象(即哪个类加载器来加载这个代理类到 JVM 的方法区),第二个参数是接口(表明你这个代理类需要实现哪些接口),第三个参数是调用处理器类实例(指定代理类中具体要干什么)

参考链接:https://www.jianshu.com/p/fa339e474c7a

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏GreenLeaves

JavaScript之面向对象的概念,对象属性和对象属性的特性简介

  一、大家都知道,面向对象语言有一个标志,那就是他们都有类的概念,通过类我们可以创建任意多个具有相同属性和方法的对象。但ECMAScript(指定JavaSc...

18260
来自专栏Janti

Java基础巩固——反射

什么是反射 ----    反射机制就是指程序运行时能够获取自身的信息。在Java中,只要给出类的名字,就可以通过反射机制来获取类的信息 哪里用的到反射机制 -...

31270
来自专栏LhWorld哥陪你聊算法

【Scala篇】--Scala初始与基础

scala 中的object是单例对象,相当于java中的工具类,可以看成是定义静态的方法的类。object不可以传参数。另:Trait不可以传参数

17310
来自专栏Python小屋

面向对象程序设计中“超类”和“子类”概念的来历

众所周知,在面向对象程序设计中,子类从超类中继承数据成员和成员方法,然后在此基础上再根据实际需要进行扩展并增加属于子类的数据成员和成员方法。也就是说,子类的对象...

30140
来自专栏mukekeheart的iOS之旅

《JavaScript高级程序设计》学习笔记(5)——面向对象编程

 欢迎关注本人的微信公众号“前端小填填”,专注前端技术的基础和项目开发的学习。   本节内容对应《JavaScript高级程序设计》的第六章内容。 1、面向对象...

29590
来自专栏猿人谷

c++---函数

一、函数的介绍     在过程化编程中, 为了将一个较大的功能顺利实现, 通常会将这个大的功能进行分解, 例如要实现一个学生信息管理系统, 一个学生信息管理系统...

20690
来自专栏大数据钻研

JavaScript 知识点整理

JavaScript是按照ECMAScript标准设计和实现的,后文说的JavaScript语法其实是ES5的标准的实现。 先说说有哪些基础语法? 最基础语法有...

29950
来自专栏精讲JAVA

粗浅看 Java 反射机制

Java 反射是 Java 被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运 行时透过 Reflection APIs 取得任何一个已知名称的cl...

36860
来自专栏Android 研究

Retrofit解析3之反射

反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。在计算机科学领域,反射是一类应用,它们能够自描述和自控制。这类应用通过某种机制来实现对自己行为的...

21220
来自专栏jessetalks

Javascript基础回顾 之(三) 面向对象

Javascript中的对象 什么是对象   我们可以把Javascript中对象理解为一组无序的键值对,就好像C#中的Dictionary<string,O...

344110

扫码关注云+社区

领取腾讯云代金券