举例理解JDK动态代理
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动态代理的更多相关文章
- 从Mybatis源码理解jdk动态代理默认调用invoke方法
一.背景最近在工作之余,把开mybatis的源码看了下,决定自己手写个简单版的.实现核心的功能即可.写完之后,执行了一下,正巧在mybatis对Mapper接口的动态代理这个核心代码这边发现一个问题. ...
- JDK动态代理深入理解分析并手写简易JDK动态代理(下)
原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-05/27.html 作者:夜月归途 出处:http://www.guitu ...
- java jdk动态代理学习记录
转载自: https://www.jianshu.com/p/3616c70cb37b JDK自带的动态代理主要是指,实现了InvocationHandler接口的类,会继承一个invoke方法,通过 ...
- 模拟实现jdk动态代理
实现步骤 1.生成代理类的源代码 2.将源代码保存到磁盘 3.使用JavaCompiler编译源代码生成.class字节码文件 4.使用JavaCompiler编译源代码生成.class字节码文件 5 ...
- jdk动态代理举例
JDK动态代理是基于接口的代理,下面举例说明 代理类:proxy,代理动作必须要基于一个proxy实例来执行 代理执行类:实现InvocationHandler,案例中是TestInvocationH ...
- java jdk动态代理模式举例浅析
代理模式概述 代理模式是为了提供额外或不同的操作,而插入的用来替代”实际”对象的对象,这些操作涉及到与”实际”对象的通信,因此代理通常充当中间人角色. java中常用的动态代理模式为jdk动态代理和c ...
- JDK动态代理深入理解分析并手写简易JDK动态代理(上)
原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-03/27.html 作者:夜月归途 出处:http://www.guitu ...
- jdk动态代理和cglib动态代理底层实现原理超详细解析(jdk动态代理篇)
代理模式是一种很常见的模式,本文主要分析jdk动态代理的过程 1.举例 public class ProxyFactory implements InvocationHandler { private ...
- 代理模式详解:静态代理、JDK动态代理与Cglib动态代理
代理模式简介分类 概念 代理,是为了在不修改目标对象的基础上,增强目标方法的业务逻辑. 客户类需要执行的是目标对象的目标方法,但是真正执行的是代理对象的代理方法,客户类对目标对象的访问是通过代 ...
随机推荐
- opencart3属性attribute实现换行等简单html代码
opencart3属性attribute在前台页面默认是没有解析html代码功能的,比如想实现换行,后台这样写:line 1<br>line 2,但前台产品页也是line 1<br& ...
- what's the 灰盒测试
what's the 灰盒测试 灰盒测试的概念:是一种综合测试的方法,他将白盒测试和黑盒测试结合在一起,构成一种无缝测试技术. 灰盒测试的思想:是基于程序运行时的外部表现又结合程序内部逻辑结构来设计测 ...
- Es6的用法
var callBack=[]; // 这个等于是个闭包,i会累加到3在做运算,所以结果都是6 ;i<=;i++) { callBack[i]=function(){ ; } } console ...
- 输入参数的默认值设定${3:-var_d}
今天看到一个不一样的写法: if [ $# != 2 ] && [ $# != 3 ] ; then #判断参数个数 echo "Invalid Args" ...
- (转)cookie和session的区别
存放位置不同 cookie数据存放在客户的浏览器上,session数据放在服务器上. 安全程度不同cookie不是很安全,别人可以解析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用 ...
- Cocos Creator JS 时间戳日期转换
/*** 时间戳换算日期* */function formatDateTime (timeStamp) { var date = new Date(); date.setTime(timeStamp ...
- zookeeper注册与发现
pom.xml添加如下引用: <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId ...
- 第一个Spring程序HelloWorld
对于初学者而言,任何理论化的讲解都比不上一个简单的HelloWorld,我们在学习Spring时也不外乎用最简单的HelloWorld程序来将这个灵活而又强大的轻量级框架推送到诸位面前.想要说明的是现 ...
- 关于Xocd升级 cocopoads无法使用的解决
最近由于工作原因,升级了下Xcode,以前是8.1现在升级到了8.3,导致无法使用了cocopoads,研究了好久终于找到了解决办法. 先描述下我的几个问题吧. 1.当运行cocopoads的时候出现 ...
- spring mvc 配置之 context:annotation-config vs component-scan
<context:annotation-config/> spring的注解@Resource.@Autowire, @Required and @Qualifier 等注解只是一个提示, ...