Kotlin 动态代理的使用以及一些坑点
Kotlin 动态代理的使用以及一些坑点
- 什么是动态代理
- 如何使用
- 坑点
什么是动态代理
在本文中,讨论的是kotlin中如何使用类似于JDK动态代理的功能,而非kotlin中by关键字实现的代理模式,所以可以说此文是介绍如何用kotlin实现JDK动态代理,至于JDK动态代理是什么,本文不予赘述,读者可自行查阅有关资料。
如何使用
在正式开始使用前,先介绍下几个比较重要的东西
- 在动态代理中,最重要的是
InvocationHandler
,因为最终实现代理就是在InvocationHandler
的invoke
方法中实现的,InvocationHandler
是一个接口,该接口中只有一个invoke
方法。 - 要被代理的类必须继承自一个接口,换句话说,要被代理的方法,必须利用接口进行声明。
下面开始正片:
- 为需要被代理的类及方法创建接口
interface IDemo{fun test(action: String, code: Int) }
- 创建实现接口的类
class Demo : IDemo{override fun test(action: String, code: Int) {println("action = [${action}], code = [${code}]")} }
- 进行代理
fun proxyTest() {val demo = Demo() // 创建要被代理的实例val proxy = Proxy.newProxyInstance( // 获取实例的代理对象Demo::class.java.classLoader, // 获取实例的classloaderarrayOf(IDemo::class.java), // 实例接口object : InvocationHandler {override fun invoke(proxy: Any, method: Method, args: Array<out Any>): Any {println("before...") // 代理增强方法val result = method.invoke(demo, *args) // 反射调用实例的原始方法if ("void" == method.genericReturnType.typeName) // 如果返回值为void, 要转换为Unit, 否则会报空指针异常return Unitreturn result}}) as IDemo // 类型转换proxy.test("hello", 123456) // 调用代理 }
- 输出
before... action = [hello], code = [123456]
坑点
- kotlin直接生成的
InvocationHandler
,其invoke
方法参数类型都是可空的,这里需要手动调整为非空,就是去掉参数类型声明后的?,一般来说这么做是没有问题的,可以参照JDK的InvocationHandler
,当然你也可以进行非空判断,至于kotlin为什么将invoke
方法的形参类型都变成了可空类型,我也不太清楚,有了解的朋友可以评论区科普一下。 - 返回类型,如果被代理方法的返回类型为
void
,那么需要在invoke
方法中返回Unit
Proxy
的newProxyInstance
第二个参数必须为接口的class数组,不能是被代理对象的class,否则会报is not interface
的异常。
最后,这篇文章属于个人经验,可能存在盲点,欢迎各位指出文中的错误之处!
Kotlin 动态代理的使用以及一些坑点相关推荐
- (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!
一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...
- 分析动态代理给Spring事务埋下的坑
前言 Spring的声明式事务让我们不在编写获得连接.关闭连接.开启事务.提交事务.回滚事务等代码,通过一个简单的@Transactional注解,就让我们轻松进行事务处理.我们知道Spring事务基 ...
- [动态代理三部曲:上] - 动态代理是如何坑掉了我4500块钱
前言 不知道,起这个名字算不算是标题党呢?不过如果小伙伴们可以耐心看下去,因为会觉得不算标题党~ 这是一个系列文章,目的在于通过动态代理这个很基础的技术,进而深入挖掘诸如:动态生成class:Clas ...
- 一次动态代理的填坑之旅
转载自 一次动态代理的填坑之旅 背景 想在现有的接口加上熔断降级或者限流的功能,比较好的方式是通过注解的方式,并基于动态代理进行实现,下面代码是Rhino的实现 @Rhino public clas ...
- spring 动态代理_分析动态代理给 Spring 事务埋下的坑
前言 Spring的声明式事务让我们不在编写获得连接.关闭连接.开启事务.提交事务.回滚事务等代码,通过一个简单的@Transactional注解,就让我们轻松进行事务处理.我们知道Spring事务基 ...
- 使用 Kotlin 协程创建动态代理
够在运行时实现接口,并决定如何在调用方法时动态执行方法.这对于在装饰器模式中描述的现有实现(尤其是来自第三方库)周围添加附加功能非常有用.然而,Kotlin协程在创建动态代理时引入了一系列新问题.我们 ...
- 填坑之动态代理生成的代理类文件在哪?
初衷 最近想研究研究Mybatis源码,了解一下Mybatis的执行过程,从mybatis-config.xml配置文件开始,一直到Mybatis执行CRUD位置,中途出现很多疑惑,今天特记录一个! ...
- Java动态代理与Cglib代理
为什么80%的码农都做不了架构师?>>> 最近又继续回来死磕Spring源码,以前看的也忘得差不多了,这次先把Spring使用的动态代理cglib看了一下,打好基础知识. cg ...
- 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | AMS 启动前使用动态代理替换掉插件 Activity 类 )
Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...
- Android插件化原理解析——Hook机制之动态代理
使用代理机制进行API Hook进而达到方法增强是框架的常用手段,比如J2EE框架Spring通过动态代理优雅地实现了AOP编程,极大地提升了Web开发效率:同样,插件框架也广泛使用了代理机制来增强系 ...
最新文章
- 列表标签ul、ol、dl、li
- Vue菜鸟之路: 封装上传组件
- 中国9大民居建筑,你都认识吗?
- 转载:CEO如何“养好CIO同时管好CIO”?
- 可以这样给DataGrid加个序号列。
- django开发中安装包时遇到的 关于 read timed out的问题的解决
- 赠送300家门店260亿销售额的零售企业Power BI实战示例数据
- java6特性_Java开发者:你应该远离的6个Java特性
- 译林 五年级上 单词_牛津译林版九年级英语上Unit1单元重点单词、词组和句型总结...
- unity 的Cinemachine组件运用
- python的循环控制_控制for循环(python)
- EXCHANGE13/16反恶意软件保护
- python-摩尔斯电码查询器
- 数据库课程设计 论坛系统—— 系统详细设计说明书
- QCC3024/QCC3020/QCC3034 对讲机(Intercom) 蓝牙耳机 替代CSR8670
- ppt背景图片怎么设置?6步教你快速搞定!
- sql server 2000企业管理器中没有项目
- ipv4和ipv6与int互转通用处理方式
- 面试总结(四)——如涵
- C语言共用体中,共用体变量的规律
热门文章
- 教你STM32官方开发板原理图下载
- 传输层协议 ——— UDP协议
- DBA 小记 — 分库分表、主从、读写分离
- 如何在生化实验中选择合适的牛血清白蛋白(BSA)?
- 徐小明:上午涨的快,跌的也…
- java工程师和全栈工程师_java全栈工程师 - 北大青鸟东莞金码学校官网
- python 吃cpu 显卡 内存_浅析 Pycharm 内存、cpu 占用率
- RSA公私钥pkcs1与pkcs8格式的转换
- 医院信息化整体解决方案
- Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.