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的目的。






发表回复