首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用CGLIB生成和增强类

用CGLIB生成和增强类
EN

Stack Overflow用户
提问于 2015-11-07 16:54:37
回答 1查看 865关注 0票数 0

代码在Scala中,但希望Java程序员也能理解。

我有以下课程:

代码语言:javascript
复制
class SampleClass {
  def test(in: String) = "Hello world!"
}

下面的代码创建了这个类的增强实例:

代码语言:javascript
复制
val e = new Enhancer
e.setSuperclass(classOf[SampleClass])
e.setCallback(new Cb)
println(e.create.asInstanceOf[SampleClass].test("foo"))

回调如下:

代码语言:javascript
复制
class Cb extends MethodInterceptor {
  override def intercept(obj: Any, m: Method, args: Array[Object], proxy: MethodProxy): Object = {
    println(s"$m is called: ${m.getName}")
    proxy.invokeSuper(obj, args)
  }
}

这个很好用。现在,如果我尝试创建一个类,然后创建它的一个新实例,那么所有方法都直接被调用,绕过回调:

代码语言:javascript
复制
val e = new Enhancer
e.setSuperclass(classOf[SampleClass])
e.setCallbackType(classOf[Cb])
println(e.createClass.newInstance.asInstanceOf[SampleClass].test("foo"))

为什么会这样呢?如何创建java.lang.Class并使用其newInstance()方法生成增强对象?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-13 22:04:32

解决了。您需要实例化实例,但要避免在进程中调用其构造函数。然后通过调用其私有方法手动绑定回调:

代码语言:javascript
复制
val instance = instantiator.newInstance.asInstanceOf[SampleClass]

val bc  = subclass.getDeclaredMethod("CGLIB$BIND_CALLBACKS", classOf[Object])
val stc = subclass.getDeclaredMethod("CGLIB$SET_THREAD_CALLBACKS", classOf[Array[Callback]])
bc .setAccessible(true)
stc.setAccessible(true)

stc.invoke(null, Array[Callback](new Cb))
bc .invoke(null, instance)
stc.invoke(null, null)

这里的instantiatorObjectInstantiator类型--使用产科来避免调用构造函数。subclass这里是由e.createClass生成的子类。

避免在过程中调用构造函数很重要,因为增强的构造函数将设置实例创建的标志,并且不可能绑定回调。顺便说一句,您还应该在整个操作之后设置此标志,以保持一致性。它的名字是构造CGLIB$

您可以看到增强构造函数如何工作这里

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

https://stackoverflow.com/questions/33585285

复制
相关文章

相似问题

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