首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >匿名类CGLib增强器

匿名类CGLib增强器
EN

Stack Overflow用户
提问于 2014-07-25 09:03:29
回答 1查看 1.3K关注 0票数 1

我正在使用CGLib来代理类。我遇到了一个问题,我无法增强匿名类,因为它们没有默认的构造函数。

我的代码如下所示:

代码语言:javascript
复制
Enhancer enhancer = new Enhancer();
enhancer.setCallback(new MethodInterceptor() { .... });
enhancer.setSuperclass(type); // type is the Class I'm trying to enhance
enhancer.create();

但是,如果增强类是匿名的(没有默认构造函数),则会引发以下异常。

代码语言:javascript
复制
java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given

有办法绕过这件事吗?

EN

回答 1

Stack Overflow用户

发布于 2014-07-25 21:35:02

JVM的验证器确保您调用有效的构造函数链。唯一的解决办法是在启动JVM时通过命令行禁用验证器,这是您通常不想做的事情,因为它给您的应用程序带来了一些不安全性。

因此,您必须调用匿名类的有效构造函数,该构造函数由cglib创建的子类模拟。因此,该类的构造函数以其封闭类的实例作为其参数。如果您使用cglib创建一个从未调用真正方法的纯代理,您可以考虑将null交给这个构造函数,但在传递参数之前仍然需要选择正确的构造函数。

您可以通过调用:

代码语言:javascript
复制
enhancer.create(new Class<?>[] {type.getEnclosingClass()}, new Object[] {null})

其中,上面的调用选择正确的构造函数并使用null值初始化匿名类的外部实例字段。

或者,您可以使用内部OpenJDK类ReflectionFactory来创建实例,而无需调用任何构造函数。在调用enhancer.createClass()之后,这是可能的。但是,这需要额外的准备,因为您需要指定不同的回调。

但是,您可能只想把cglib放在一起。作为一个免责声明,我是另一个库的作者,我想推荐给你。使用字节巴迪,您在创建类方面有更多的自由,使用它来定义您的逻辑更容易。使用Buddy,你可以写

代码语言:javascript
复制
new ByteBuddy()
  .subclass(type)
  .method(any()).intercept(MethodDelegation.to(new Object() {
     @RuntimeType
     public Object intercept(@SuperCall Callable<?> c, 
                             @Origin Method m, 
                             @AllArguments Object[] a) throws Exception {
       // implement your interception logic
     }
   }).make();

实现同样的逻辑。只需删除调用侦听所不需要的(带注释的)参数。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24951944

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档