Java: JDK11后的动态代理方法

Java: JDK11后的动态代理方法

java 11 以后对于反射进行了更严格的限制,因此之前的很多代理框架,动态代理的实现方法都无效了,后来我查看了Spring的做法,才注意到一个新的动态代理框架:Bytebuddy。

当然,这些失效的代理方法是不包括java自己的JDK代理的。

概述

ByteBuddy是一个可以在高版本的Java中使用的类库,虽然它可以很好的在高版本的Java中使用,但是,同样存在着一个小问题,它生成的类,将会出现在unnamed-model中,这种未命名的模块常常会带来一些问题,但是在目前的Java体系中,这不可避免。

ByteBuddy采用一种链式的API来进行代理操作,这是一种Builder模式,提供了相当丰富的代理操作,但是如果和ASM或者JavaAssets相比,还是有很多的限制,它不能像这二者一样通过类似源码的东西动态的生成一个Class,不过如果单纯需要使用代理来做一些AOP的话,这反而是一种简化,使得整个API变得更加便利。

使用ByteBuddy进行AOP代理

ByteBuddy本身提供了不少方法来对类进行修饰,他可以创建子类,创建枚举,接口,添加注解等,对于AOP来说,最常见的一种做法就是对一个类进行子类化(继承),并且通过Handler拦截其中的方法,对于ByteBuddy来说,这种操作的实现也非常简单:

// ByteBuddy 代理开始 
ByteBuddy byteBuddy = new ByteBuddy();
byteBuddy.subclass(target.getClass()) // 被代理的Class
    .method(ElementMatchers.any())  // 匹配需要代理的方法
    .intercept(InvocationHandlerAdapter.of(handler)) // 代理使用的Handler,这里直接用了JDK的那个InvocationHandler
    .name(target.getClass().getName() + "$Proxied") // 生成代理类的全限定名
    .make() // 生成Class
    .load(target.getClass().getModule().getClassLoader()) // 加载到指定的ClassLoader
    .getLoaded() // 获取加载的Class
    .getConstructor() // 读取它的构造方法
    .newInstance(); // 创建代理对象
// ByteBuddy 代理结束

如上所示,就完成了对target对象的集成,并且通过invocationHandler对此类的全部方法进行拦截,用以达到AOP的目的。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Fantastic Soft

风铃之书是个人的工作和生活的总结和分享的站点,欢迎来访和留言,有时也会提供自家软件的发布版本和开源项目。