Kotlin 动态代理的使用以及一些坑点

  • 什么是动态代理
  • 如何使用
    • 坑点

什么是动态代理

在本文中,讨论的是kotlin中如何使用类似于JDK动态代理的功能,而非kotlin中by关键字实现的代理模式,所以可以说此文是介绍如何用kotlin实现JDK动态代理,至于JDK动态代理是什么,本文不予赘述,读者可自行查阅有关资料。

如何使用

在正式开始使用前,先介绍下几个比较重要的东西

  • 在动态代理中,最重要的是InvocationHandler,因为最终实现代理就是在InvocationHandlerinvoke方法中实现的,InvocationHandler是一个接口,该接口中只有一个invoke方法。
  • 要被代理的类必须继承自一个接口,换句话说,要被代理的方法,必须利用接口进行声明。

下面开始正片:

  1. 为需要被代理的类及方法创建接口

    interface IDemo{fun test(action: String, code: Int)
    }
    
  2. 创建实现接口的类
    class Demo : IDemo{override fun test(action: String, code: Int) {println("action = [${action}], code = [${code}]")}
    }
    
  3. 进行代理
    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) // 调用代理
    }
    
  4. 输出
    before...
    action = [hello], code = [123456]
    

坑点

  1. kotlin直接生成的InvocationHandler,其invoke方法参数类型都是可空的,这里需要手动调整为非空,就是去掉参数类型声明后的?,一般来说这么做是没有问题的,可以参照JDK的InvocationHandler,当然你也可以进行非空判断,至于kotlin为什么将invoke方法的形参类型都变成了可空类型,我也不太清楚,有了解的朋友可以评论区科普一下。
  2. 返回类型,如果被代理方法的返回类型为void,那么需要在invoke方法中返回Unit
  3. ProxynewProxyInstance第二个参数必须为接口的class数组,不能是被代理对象的class,否则会报is not interface的异常。

最后,这篇文章属于个人经验,可能存在盲点,欢迎各位指出文中的错误之处!

Kotlin 动态代理的使用以及一些坑点相关推荐

  1. (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!

    一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...

  2. 分析动态代理给Spring事务埋下的坑

    前言 Spring的声明式事务让我们不在编写获得连接.关闭连接.开启事务.提交事务.回滚事务等代码,通过一个简单的@Transactional注解,就让我们轻松进行事务处理.我们知道Spring事务基 ...

  3. [动态代理三部曲:上] - 动态代理是如何坑掉了我4500块钱

    前言 不知道,起这个名字算不算是标题党呢?不过如果小伙伴们可以耐心看下去,因为会觉得不算标题党~ 这是一个系列文章,目的在于通过动态代理这个很基础的技术,进而深入挖掘诸如:动态生成class:Clas ...

  4. 一次动态代理的填坑之旅

    转载自  一次动态代理的填坑之旅 背景 想在现有的接口加上熔断降级或者限流的功能,比较好的方式是通过注解的方式,并基于动态代理进行实现,下面代码是Rhino的实现 @Rhino public clas ...

  5. spring 动态代理_分析动态代理给 Spring 事务埋下的坑

    前言 Spring的声明式事务让我们不在编写获得连接.关闭连接.开启事务.提交事务.回滚事务等代码,通过一个简单的@Transactional注解,就让我们轻松进行事务处理.我们知道Spring事务基 ...

  6. 使用 Kotlin 协程创建动态代理

    够在运行时实现接口,并决定如何在调用方法时动态执行方法.这对于在装饰器模式中描述的现有实现(尤其是来自第三方库)周围添加附加功能非常有用.然而,Kotlin协程在创建动态代理时引入了一系列新问题.我们 ...

  7. 填坑之动态代理生成的代理类文件在哪?

    初衷 最近想研究研究Mybatis源码,了解一下Mybatis的执行过程,从mybatis-config.xml配置文件开始,一直到Mybatis执行CRUD位置,中途出现很多疑惑,今天特记录一个! ...

  8. Java动态代理与Cglib代理

    为什么80%的码农都做不了架构师?>>>    最近又继续回来死磕Spring源码,以前看的也忘得差不多了,这次先把Spring使用的动态代理cglib看了一下,打好基础知识. cg ...

  9. 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | AMS 启动前使用动态代理替换掉插件 Activity 类 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  10. Android插件化原理解析——Hook机制之动态代理

    使用代理机制进行API Hook进而达到方法增强是框架的常用手段,比如J2EE框架Spring通过动态代理优雅地实现了AOP编程,极大地提升了Web开发效率:同样,插件框架也广泛使用了代理机制来增强系 ...

最新文章

  1. 列表标签ul、ol、dl、li
  2. Vue菜鸟之路: 封装上传组件
  3. 中国9大民居建筑,你都认识吗?
  4. 转载:CEO如何“养好CIO同时管好CIO”?
  5. 可以这样给DataGrid加个序号列。
  6. django开发中安装包时遇到的 关于 read timed out的问题的解决
  7. 赠送300家门店260亿销售额的零售企业Power BI实战示例数据
  8. java6特性_Java开发者:你应该远离的6个Java特性
  9. 译林 五年级上 单词_牛津译林版九年级英语上Unit1单元重点单词、词组和句型总结...
  10. unity 的Cinemachine组件运用
  11. python的循环控制_控制for循环(python)
  12. EXCHANGE13/16反恶意软件保护
  13. python-摩尔斯电码查询器
  14. 数据库课程设计 论坛系统—— 系统详细设计说明书
  15. QCC3024/QCC3020/QCC3034 对讲机(Intercom) 蓝牙耳机 替代CSR8670
  16. ppt背景图片怎么设置?6步教你快速搞定!
  17. sql server 2000企业管理器中没有项目
  18. ipv4和ipv6与int互转通用处理方式
  19. 面试总结(四)——如涵
  20. C语言共用体中,共用体变量的规律

热门文章

  1. 教你STM32官方开发板原理图下载
  2. 传输层协议 ——— UDP协议
  3. DBA 小记 — 分库分表、主从、读写分离
  4. 如何在生化实验中选择合适的牛血清白蛋白(BSA)?
  5. 徐小明:上午涨的快,跌的也…
  6. java工程师和全栈工程师_java全栈工程师 - 北大青鸟东莞金码学校官网
  7. python 吃cpu 显卡 内存_浅析 Pycharm 内存、cpu 占用率
  8. RSA公私钥pkcs1与pkcs8格式的转换
  9. 医院信息化整体解决方案
  10. Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.