8

我工作的某个人注意到(在堆栈跟踪中)当使用 -javaagent:spring-instrumentation.jar 运行 jvm 时,我的 JAXB 注释类中有一些我们没有编写的奇怪的新方法:例如 SomeJaxbAnnotatedClass$JaxbAccessorM_getFields_setFields_java_util_Set.get

这是否意味着 jaxb 在可用时使用字节码检测?我在哪里可以阅读有关此功能的更多信息?

谢谢,尤瓦尔

4

4 回答 4

12

只是对 skaffman 帖子的补充:

您看到的 (SomeJaxbAnnotatedClass$JaxbAccessor...) 是一个内部类,它是由 JAXB 参考实现动态生成的。为了防止运行时的反射开销,在使用反射绕过受保护的访问修饰符之后,通过调用 ClassLoader.defineClass(String, byte[], int, int) 生成类的具体实现的字节码com.sun.xml.bind.v2.runtime.reflect.Accessor并注入到当前的类加载器中定义类方法。

因此,JAXB 参考实现并不是在修改现有类的意义上检测字节码,而是生成新类以优化运行时性能。

于 2010-01-25T17:18:04.073 回答
8

启动时JaxbContext,它会执行大量反射操作,以预缓存以后需要的所有内容。这样做是出于性能原因。我不确定它到底做了什么,但我希望它能够执行某种运行时类生成逻辑,因为它在运行时会比原始反射更快。

有趣的是,您可以通过设置未记录的系统属性来关闭此行为,这会提高上下文的启动,但会牺牲运行时性能。

编辑:我应该强调这是 Sun JAXB 参考实现在幕后所做的,它不是 JAXB 规范的一部分。其他实现可以自由地做任何他们选择的事情。

于 2010-01-25T16:34:16.190 回答
1

最后我检查了一下,JAXB 使用反射来生成基于您提供的 XML 的类(尽管我已经有一段时间没有使用它了,所以他们可能已经改变了他们的方法)。

另一方面,我知道JiBX使用BCEL来执行字节码检测。这是一篇关于此的文章:http: //www.ibm.com/developerworks/java/library/j-cwt09065/

于 2010-01-25T16:30:02.470 回答
0

正如 skaffman 所提到的,您可以通过设置系统属性来关闭所有这些内部类的生成:com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.fastBoot=true

当然,它没有记录在案,但多年来一直没有改变。

于 2017-11-09T15:34:54.153 回答