出于好奇,除了cglib之外,是否有任何(稳定)开源项目用于运行时Java代码生成?我为什么要使用它们?
“显示标记为“ java-asm”的问题”)
CGLIB和几乎所有其他库都建立在ASM之上,而ASM本身的作用很低。对于大多数人来说,这是一个阻止因素,因为您必须了解字节码和一些JVMS才能正确使用它。但是掌握ASM无疑是非常有趣的。但是请注意,尽管有
出色的 ASM4指南,但在API的某些部分中,javadoc文档可能非常简洁(如果存在的话),但仍在改进中。它紧密遵循JVM版本以支持新功能。
但是,如果您需要完全控制,ASM是您的首选武器。
该项目定期更新; 在2015年5月15日发布此编辑版本5.0.4时。
Byte Buddy是一个相当新的库,但是提供了CGLIB或Javassist提供的任何功能以及更多功能。Byte
Buddy可以完全自定义到字节代码级别,并带有一种表达性强的领域特定语言,允许非常可读的代码。
Javassist的建议或自定义工具代码基于简单的代码,
String
因此无法在此代码中进行类型检查和调试,而ByteBuddy允许使用纯Java编写代码并因此进行类型检查并允许调试。
用户回调可以配置有注释,以允许在回调中接收所需的参数。
漂亮的代理构建器允许ByteBuddy用作纯代理或附加代理。它允许不同的种类
该API的主要缺点也许是,对于初学者来说有点冗长,但它被设计为一种像代理代DSL一样的可选API;没有魔术或可疑的默认值。在处理字节码时,它可能是最安全,最合理的选择。同样,有多个示例和大量教程,这不是真正的问题。
在2015年10月,该项目获得了OracleDuke的选择奖。此时,它刚刚达到了1.0.0里程碑,这是一个很大的成就。
请注意,mockito已在2.1.0版中将ByteBuddy替换为CGLIB。
Javassist
Javassist的Javadoc比CGLIB更好。类工程API可以,但是Javassist也不完美。特别是,ProxyFactory
它等同于CGLIB的Enhancer
缺点,仅列举了一些缺点:
ClassloaderProvider
是一个静态字段,那么它适用于同一类加载器中的所有实例ProxyFactory
。在面向方面方面,可以将代码注入代理中,但是Javassist中的这种方法是有限的,并且容易出错:
Javassist也被认为比Cglib慢。这主要是由于其读取类文件的方法,而不是像CGLIB这样读取已加载的类的方法。而且实现本身很难理解为公平;
如果需要更改Javassist代码,则有很多机会破坏某些东西。
Javassist也遭受了不活动的困扰,他们被证明在2013年左右迁移到github似乎很有用,因为它显示了定期的提交和来自社区的请求。
这些限制仍然存在于3.17.1版中。该版本已被升级到3.20.0版本,但是Javassist似乎仍然对Java 8支持存在问题。
JiteScript看起来确实是为ASM精心设计DSL的新作品,它基于最新的ASM版本(4.0)。该代码看起来很干净。
但是 该项目尚处于早期阶段,因此可以更改API /行为,而且文档非常糟糕。并更新稀缺,如果不放弃。
乔德
这是一个相当新的工具,但是它提供了迄今为止最好的 人工 API。它允许使用不同类型的代理,例如子类代理(cglib方法)或编织或委派。
尽管这是相当少见的,但如果运作良好,则没有任何信息。在处理字节码时,有很多特殊情况需要处理。
AspectJ
AspectJ是用于 面向方面的编程
的非常强大的工具(仅)。AspectJ通过操纵字节码来实现其目标,以便您可以由此实现目标。但是,这需要在编译时进行操作。从2.5版4.1.x开始,Spring通过代理在加载时进行编织。
cglib
自问这个问题以来,有关CGLIB的词汇已更新。
CGLIB的运行速度非常快,这是它仍然存在的主要原因之一,而且CGLIB的运行几乎比现在(2014-2015年)的任何替代产品都要好。
一般来说,允许在运行时重写类的库必须避免在重写相应类之前加载任何类型。因此,它们不能使用Java反射API,而Java反射API要求加载反射中使用的任何类型。相反,他们必须通过IO(这是性能破坏者)读取类文件。例如,这使得Javassist或Proxetta比Cglib慢得多,后者仅通过反射API读取方法并覆盖它们。
但是,CGLIB不再处于积极开发中。 有最新版本,但是许多人认为这些更改微不足道,并且大多数人从未更新到版本3,因为CGLIB
3.1版解决了3.0版的许多问题(因为4.0.3版Spring框架重新打包了3.1版)。
在最新版本中引入了一些严重的错误,但实际上并没有建立信心。
而且,CGLIB源代码的质量很差,因此我们看不到新的开发人员加入CGLIB项目。要了解CGLIB的活跃性,请参阅他们的邮件列表。
请注意,遵循guice邮件列表上的命题之后,CGLIB现在可以在github上使用,以使社区能够更好地帮助该项目,它似乎正在工作(多次提交和请求,ci,更新的maven),但仍然存在大多数问题。
目前,正在开发3.2.0版,并且他们将精力集中在Java 8上,但是到目前为止,想要Java 8支持的用户必须在构建时使用技巧。但是进展非常缓慢。
CGLIB仍然因PermGen内存泄漏而困扰。但是其他项目可能没有经过这么多年的战斗测试。
编译时注释处理
注释处理
当然,这不是运行时,而是生态系统的重要组成部分,大多数代码生成用法不需要创建运行时。
从Java 5开始,Java 5带有单独的命令行工具来处理批注:apt
,从Java 6开始,批注处理已集成到Java编译器中。
在某些时候,您需要显式地传递处理器,现在通过这种ServiceLoader
方法(只需将此文件添加META- INF/services/javax.annotation.processing.Processor
到jar中),编译器就可以自动检测注释处理器。
这种代码生成方法也有缺点,它也需要大量工作,并且需要理解Java语言而不是字节码。该API有点麻烦,并且因为它是编译器中的插件,因此必须格外小心,以使该代码成为最有弹性和用户友好的错误消息。
这里最大的好处是,它避免了运行时的另一个依赖关系,可以避免permgen内存泄漏。并且可以完全控制生成的代码。
在2002年
CGLIB定义了一个新的标准来轻松地操作字节码。当今我们拥有的许多工具和方法(CI,覆盖范围,TDD等)当时都不可用或尚未成熟。十多年来,CGLIB一直与时俱进;
这是一个相当不错的成就。与直接操作操作码相比,它的运行速度快且具有易于使用的API。
它定义了有关代码生成的新标准,但如今由于环境和要求已发生变化,因此不再存在,标准和目标也已发生变化。
JVM已更改,并将在最近和将来的Java(7/8/9/10)版本(调用动态,默认方法,值类型等)中更改。ASM定期升级他的API和内部组件以适应这些更改,但是CGLIB和其他人员尚未使用它们。
尽管注释处理越来越受青睐,但它不像运行时生成那样灵活。
截至2015年, 虽然 Byte Buddy刚刚出现 , 但它 为运行时生成提供了最引人注目的 卖点
。相当不错的更新速度,并且作者对Java字节码内部知识非常了解。
有哪些可用的web UI自动化框架? 我知道这个问题,但它是3年前问的,从那时起事情发生了很大的变化。我只是想看看这个问题的答案是否仍然相关,或者从那以后已经开发了更新更好的工具。 我再问一次,因为在做了一些谷歌搜索后,我偶然发现了Geb和Capybara等工具,这些工具在该问题中没有被提及作为答案。
问题内容: 问题 在解决这个问题之后,似乎基于文件或磁盘的实现可能是解决我在此处提到的问题的正确解决方案。精简版: 目前,我已将实施为。 条目以相当固定的速率连续添加到其中。稍后对此进行详细说明。 最终,无论如何,这意味着JVM耗尽了堆空间。 在工作中,(强烈)建议我使用SQLite解决此问题,但是在问了上一个问题之后,我认为数据库不是适合此工作的合适工具。所以- 让我知道这听起来是否疯狂 -我认
问题内容: py2exe是否有替代品? 问题答案: cx_Freeze是跨平台的,并且具有相同的功能,或者您可以使用py2app,它仅在Mac上有效。
问题内容: 一个(很久以前),我写了一个网络蜘蛛,我对该线程进行了多线程处理,以使并发请求能够同时发生。那是我的Python青年时代,在我了解GIL及其为多线程代码造成的相关麻烦之前(IE,大多数时候,这些东西最终都被序列化了!)… 我想对这段代码进行重做,以使其更健壮并性能更好。基本上有两种方法可以执行此操作:我可以使用2.6+中的新多处理模块,也可以使用某种基于反应堆/事件的模型。我宁愿以后再
问题内容: 另一种选择是允许我填写带有复选框和单选按钮的HTML表单。 我正在创建一个需要用户输入的Android应用程序,并将该数据使用html表单发送到网站,然后将其填写,提交表单并返回以下结果页面。 我已经设法在eclipse中使用HtmlUnit库将数据发送到html表单并检索页面(我在下面发布了Java代码)。 但是,当我将该代码复制到我的Android项目中时,我发现Android不支
问题内容: 我听说过很多有关Lucene的内容,它是Java中最好的搜索引擎库之一。Ruby是否有任何类似(功能强大)的库? 问题答案: 好吧,有Ferret,这是Lucene到Ruby的港口。此外,如果您愿意,可以从JRuby中轻松使用Lucene 。 根据您的需求,您可能还需要看一下Solr,它是基于Lucene构建的高级前端。有一个Ruby接口solr- ruby ,它通过HTTP与Solr