JDK动态代理

说到java自带的动态代理api,肯定离不开反射。JDK的Proxy类实现动态代理最核心的方法:

public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)

这个方法的作用:在运行时,动态创建一组指定接口的实现类对象。其中的三大参数:

  • ClassLoader loader

    • 类加载器,主要作用是用来加载类的,把.class文件加载到jvm的方法区中,形成class对象
  • Class<?>[] interfaces

    • 实现的接口列表
  • InvocationHandler h

    • InvocationHandler 是一个接口,里面有且只有一个方法invoke(Object proxy, Method method, Object[] args),后面会介绍。

我们可以先看个简单的例子:

public class DynamicProxyDemo {

    @Test
public void test1() { ClassLoader loader = this.getClass().getClassLoader();
Class[] classes = {Human.class, Car.class};
InvocationHandler h = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("来了,老弟~");
return null;
}
}; Human human = (Human) Proxy.newProxyInstance(loader, classes, h);
human.male();
human.toString();
human.getClass();
} } interface Human {
Object male();
} interface Car {
Object bmw();
}

​ 输出:

来了,老弟~
来了,老弟~

可以看到,代码并没有报错,因为Proxy.newProxyInstance(loader, classes, h)返回的对象是实现了指定接口的类对象,所以强转成Human没有问题,当调用Human对象的方法时,会执行InvocationHandler里的invoke方法的语句。但是我当我调用getClass()方法时,并没有执行对应的语句,这是由于此方法是native方法,是调用本地的方法。

既然调用代理对象的所有方法(个别除外)都会调用某个方法(invoke()),我们可以在里面进行任意操作,达到前置或者后置增强的效果。

以下这图可以解析invoke(Object proxy, Method method, Object[] args)方法里的参数和human接口带参数的方法之间的关系:

输出:

来了,老弟~
科比

此方法也包含三大参数:

  • Object proxy

    • 当前对象,即生成的代理对象
  • Method method
    • 当前被调用的方法,即目标方法
  • Object[] args
    • 方法传入的参数

未完待续。

举例理解JDK动态代理的更多相关文章

  1. 从Mybatis源码理解jdk动态代理默认调用invoke方法

    一.背景最近在工作之余,把开mybatis的源码看了下,决定自己手写个简单版的.实现核心的功能即可.写完之后,执行了一下,正巧在mybatis对Mapper接口的动态代理这个核心代码这边发现一个问题. ...

  2. JDK动态代理深入理解分析并手写简易JDK动态代理(下)

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-05/27.html 作者:夜月归途 出处:http://www.guitu ...

  3. java jdk动态代理学习记录

    转载自: https://www.jianshu.com/p/3616c70cb37b JDK自带的动态代理主要是指,实现了InvocationHandler接口的类,会继承一个invoke方法,通过 ...

  4. 模拟实现jdk动态代理

    实现步骤 1.生成代理类的源代码 2.将源代码保存到磁盘 3.使用JavaCompiler编译源代码生成.class字节码文件 4.使用JavaCompiler编译源代码生成.class字节码文件 5 ...

  5. jdk动态代理举例

    JDK动态代理是基于接口的代理,下面举例说明 代理类:proxy,代理动作必须要基于一个proxy实例来执行 代理执行类:实现InvocationHandler,案例中是TestInvocationH ...

  6. java jdk动态代理模式举例浅析

    代理模式概述 代理模式是为了提供额外或不同的操作,而插入的用来替代”实际”对象的对象,这些操作涉及到与”实际”对象的通信,因此代理通常充当中间人角色. java中常用的动态代理模式为jdk动态代理和c ...

  7. JDK动态代理深入理解分析并手写简易JDK动态代理(上)

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-03/27.html 作者:夜月归途 出处:http://www.guitu ...

  8. jdk动态代理和cglib动态代理底层实现原理超详细解析(jdk动态代理篇)

    代理模式是一种很常见的模式,本文主要分析jdk动态代理的过程 1.举例 public class ProxyFactory implements InvocationHandler { private ...

  9. 代理模式详解:静态代理、JDK动态代理与Cglib动态代理

    代理模式简介分类 概念 ​ 代理,是为了在不修改目标对象的基础上,增强目标方法的业务逻辑. ​ 客户类需要执行的是目标对象的目标方法,但是真正执行的是代理对象的代理方法,客户类对目标对象的访问是通过代 ...

随机推荐

  1. Android 跨进程数据共享

    Android 开发过程中,基于功能隔离.进程安全.进程保活等等考虑,我们经常需要为应用划分进程,然后不得不面临跨进程通信和跨进程共享数据的挑战. 跨进程通信 相对来说,跨进程通信比较简单,常用的方式 ...

  2. afn3.0源码解析---AFURLRequestSerialization

    AFHTTPRequestSerialization: @方法1 - (NSMutableURLRequest *)requestWithMethod:(NSString *)method URLSt ...

  3. windows red5相关

    red5部署 前段时间把red5服务器搭建好了,现在记录下是如何搭建的.1,下载对应版本的red5https://github.com/Red5/red5-server/releases2,如果没有安 ...

  4. linux pwd命令 显示当前所在路径

    pwd 显示当前所在路径 [root@MongoDB ~]# pwd /root

  5. kubernetes命令详情

    查看客户端和服务器侧的版本信息 kubectl version 列出当前版本的kubernetes的服务器端所支持的api版本信息 kubectl api-versions 查看帮助,语法格式 kub ...

  6. js类型转换比较表格

    JavaScript类型转换表格  值 转换为         字符串 数字 布尔值 对象 undefined "undefined" NaN false throw TypeEr ...

  7. btcpool之BlockMaker

    一.简介 BlockServer将StratumServer发送的solvedshare数据(块头和coinbase交易)与GbtMaker发送的rawgbt数据(其他交易)一起组装成一个块,然后通过 ...

  8. jmeter-PC注册遇到的问题与解决

    2019-04-26问题:

  9. [LeetCode] 45. Jump Game II_ Hard tag: Dynamic Programming

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  10. virtual dom 简单了解

    管理应用程序状态和用户界面的同步一直是前端UI开发复杂性的主要来源.目前出现了不同的方式来处理这个问题.本文简单讨论其中一种方式virtual dom. 文章概要: virtual dom 基本概念, ...