JAXB 是否使用字节码检测?
我工作的人注意到(在 stacktrace 中),当使用 -javaagent:spring-instrumentation.jar 运行 jvm 时,我的 JAXB 带注释的类中有一些我们没有编写的奇怪的新方法:例如 SomeJaxbAnnotatedClass$JaxbAccessorM_getFields_setFields_java_util_Set.get
这是否意味着jaxb 在可用时使用字节码检测吗?我在哪里可以阅读有关此功能的更多信息?
谢谢, 尤瓦尔
Someone where i work noticed (in stacktrace) that when running the jvm with -javaagent:spring-instrumentation.jar my JAXB annotated classes have strange new methods in them which we didn't write: e.g. SomeJaxbAnnotatedClass$JaxbAccessorM_getFields_setFields_java_util_Set.get
Does this mean that jaxb uses bytecode instrumentation when it is available? Where can i read more about this functionality?
Thanks,
Yuval
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
只是对 skaffman 的帖子的补充:
您所看到的 (SomeJaxbAnnotatedClass$JaxbAccessor...) 是一个内部类,它是由 JAXB 参考实现动态生成的。为了防止运行时的反射开销,会生成类
com.sun.xml.bind.v2.runtime.reflect.Accessor
的具体实现的字节码,并通过调用 ClassLoader.defineClass 将其注入到当前类加载器中(String, byte[], int, int),使用反射绕过defineClass方法的protected访问修饰符后。因此,JAXB 参考实现并不是在修改现有类的意义上对字节码进行检测,而是生成新类以优化运行时性能。
Just an addition to skaffman's post:
What you see (SomeJaxbAnnotatedClass$JaxbAccessor...) is an inner class, which is generated dynamically by the JAXB reference implementation. To prevent reflection overhead at runtime, bytecode for the concrete implementations of the class
com.sun.xml.bind.v2.runtime.reflect.Accessor
are generated and injected into the current classloader by invoking ClassLoader.defineClass(String, byte[], int, int), after using reflection to circumvent the protected access modifier of the defineClass method.So, the JAXB reference implementation is not instrumenting bytecode in the sense that it's modifying existing classes, but generates new classes for optimized runtime performance.
当 JaxbContext 启动时,它会执行大量反射操作,以预先缓存稍后需要的所有内容。这样做是出于性能原因。我不确定它到底做了什么,但我希望它执行某种运行时类生成逻辑,因为这在运行时比原始反射更快。
有趣的是,您可以通过设置未记录的系统属性来关闭此行为,这会改善上下文的启动,但会牺牲运行时性能。
编辑:我应该强调,这是 Sun JAXB 参考实现在幕后所做的事情,它不是 JAXB 规范的一部分。其他实现可以自由地做他们选择的任何事情。
When the
JaxbContext
starts up, it performs a large amount of reflection operations, to pre-cache all of the stuff it will later need. This is done for performance reasons. I'm not sure what it does exactly, but I would expect it to perform some kind of runtime class generation logic, since that will be faster at runtime than raw reflection.Interestingly, you can turn this behaviour off by setting a non-documented system property, which improves the startup of the context, at the expense of runtime performance.
edit: I should stress that this is what the Sun JAXB reference implementation does under the covers, it's not part of the JAXB spec. Other implementations are free to do whatever they choose.
最后我检查了一下,JAXB 使用反射根据您提供的 XML 生成类(尽管我已经有一段时间没有使用它了,所以他们可能已经改变了方法)。
另一方面,我知道 JiBX 使用 BCEL 执行字节码检测。这是一篇相关文章: http://www.ibm.com/ developerworks/java/library/j-cwt09065/。
Last I checked, JAXB uses reflection to generate classes based on the XML you provide (though I haven't used it in some time, so they may have changed their methodology).
I know that JiBX, on the other hand, uses BCEL to perform bytecode instrumentation. Here is an article about that: http://www.ibm.com/developerworks/java/library/j-cwt09065/.
正如 skaffman 所提到的,您可以通过设置系统属性来关闭所有这些内部类的生成: com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.fastBoot=true
当然,它没有记录在案,但它还没有'多年来一直没有改变。
As mentioned by skaffman you can turn off the generation of all those inner classes by setting the system property : com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.fastBoot=true
Of course it's not documented, but it hasn't changed for years.