只是出于好奇,是否有任何(稳定的)开放源码项目运行时java代码生成的其他比cglib?为什么我应该使用他们?

有帮助吗?

解决方案

ASM

CGLIB和几乎所有其他图书馆是建造在小型矿其本身的行为在一个非常低的水平。这是一个表明塞于大多数人因为你必须了解字节的代码和一点的 JVM 正确使用它。但掌握ASM是肯定非常有趣的。但请注意,虽然有一个 伟大的 ASM4导, 在一些API的一部分的如果是的话,为什么不试文件可以是非常简明扼要,如果它存在的一切,但它正在得到改善。它密切合作下JVM版本,以支持新的特点。

然而,如果您需要完全控制,ASM是你选择的武器。

这个项目中看到了定期更新;在这个编辑版本5.0.4被释放可能的15 2015年。

字节哥们

字节的伙伴是一个相当新的图书馆,但提供的任何功能CGLIB或Javassist提供以及更多。字节的伙伴可以完全定下来的字节的代码水平,并配有一个表现域特定的语言,允许为非常可读的编码。

  • 它支持所有JVM码版本,包括Java8义的改变的一些操作码有关的默认方法。
  • ByteBuddy似乎并不受到缺陷的其他图书馆
  • 高配置
  • 相当快的速度(基准 代码)
  • 类型的安全流利API
  • 类安全的回调

    Javassist建议或定义的规范代码是基于码在一个普通的 String 此类检查和调试是不可能的内的这个代码,而ByteBuddy允许写那些纯Java因此强制执行的类型检查,并允许调试。

  • 注驱动(性)

    用户回调可构成附有说明的允许收到希望参数的回调。

  • 可作为一个代理

    漂亮剂的建设者允许ByteBuddy被用作为一个纯粹的剂或作为附加剂。它允许不同种类的

  • 很好的记录
  • 很多例子
  • 干净的代码,~94%测试的复盖范围
  • 安卓DEX支持

主要缺点也许会的API是一位详细,对于一个初学者,但它设计为一个选择API形作为代理代DSL;有没有魔法或可疑违约。当操纵字节的代码这可能是最安全和最合理的选择。还有多例子和一个大的教程,这不是一个真正的问题。

在2015年十月这个项目收到的 Oracle公爵的选择奖.在这个时候,它只是到达 的1.0.0里程碑, ,这是一个相当成就。

注意, 已经取代 CGLIB字节哥们 在2.1.0版本.

Javassist

对如果是的话,为什么不试的Javassist是比这更好的CGLIB.这类工程API是好的,但Javassist不是完美的。特别是, ProxyFactory 这相当于CGLIB的 Enhancer 遭受的一些缺点也一样,只是列几个:

  • 桥的方法是不完全的支持(即一个是产生协变回归类型)
  • ClassloaderProvider 是一个静态的领域,而不是,那么它适用于所有的实例,在同一类装入器
  • 定义命名可能已经欢迎(与检查罐子签名)
  • 没有扩展一点,几乎所有的方法感兴趣的是私人的,麻烦如果我们想要改变某些行为
  • 同时Javassist提供支持标注特性类别,他们不支持 ProxyFactory.

在这方面向侧面,一个可以注射代码代理,但这种做法在Javassist是有限的和有点容易出错:

  • 方面的代码被写在一个普通的Java字符串 编制 在操作码
  • 没有类型的检查
  • 没有仿制药
  • 没有氧
  • 没有自动(联合国)拳击

还Javassist被认为是慢于Cglib.这主要是由于其方法的阅读类文件而不是读载的课程,例如CGLIB。和 执行情况 本身是难以阅读可以公平;如果一个需要作出改变的Javassist码还有许多的机会来打破点东西。

Javassist遭受的不活动以及他们移动来 审查大约在2013年 似乎已经证明是有益的,因为它显示了正常的提交和拉的请求从社区。

这些限制仍然站在版3.17.1.版本已经碰到的版本3.20.0,但它似乎Javassist可能仍有问题Java8的支持。

JiteScript

JiteScript不会看起来像一块新的很好的成DSL体和小型的,这是基于最新的先进电子发布(4.0).代码看起来干净。

该项目仍处在其早期的年龄,使API/行为改变,加上本文件是严峻的。和更新稀少,如果不放弃。

Proxetta

这是一个相当新的工具,但它提供了迄今为止最好的 API。它允许对不同类型的代理人,如亚类代理(cglib方法),或者织或代表团。

虽然,这是一个相当罕见,不存在信息,如果它运行良好。有很多角落的情况下处理当处理码。

模型或许

模型或许是一个非常强大的工具 面向方面的编程 (只)。模型或许操纵字节的代码实现其目标这样的,你可能能够实现自己的目标。然而,这需要操纵在编译时间;春天提供织在装载时通过代理人以来的版本 2.5, 4.1.x.

CGLIB

一个字CGLIB,已经更新,因为这个问题已经问。

CGLIB是相当快的,这是一个主要原因为什么它仍然是在周围,随着事实,即CGLIB的工作几乎比任何替代品,直到现在(2014-2015).

一般而言的库允许改写的课程在运行时必须避免装载任何类型之前的相应的类中进行改写。因此,他们不能使用的Java反射API这需要,任用类型的反映是加载。相反,他们已经阅读类文件通过IO(其是断路器的).这使得例如Javassist或Proxetta大大慢于Cglib这只是读取的方法通过反射API和替代他们。

然而,CGLIB不再在积极发展。那里是最近的版本,但这些变化被认为微不足道的许多和大多数人有没有从来没有更新版3以来CGLIB介绍了一些 严重的错误 在最后版本没有什么真正构建起来的信心。 3.1版固定的很多的困境的3.0版本(由于版4.0.3弹框架内重新包装 3.1版).

此外,CGLIB源代码是的而不是 质量差的 这样,我们没有看到新的开发者加入CGLIB项目。对于一个印象CGLIB的积极性,看到他们的 邮件列表.

注意,下一个 提议在题之一,因邮件列表,CGLIB现在可以在 要使社区更好地帮助的项目,这似乎是工作(多承诺和拉的请求,ci、更新专家),但大多数问题仍然存在。

在这个时候,有工作上的版本3.2.0,并且它们重点的努力Java8,但是迄今为止的用户要java8支持必须使用的技巧,在建立时间。但进展非常缓慢。

和CGLIB仍然是已知的困扰,为永久代记忆丢失。但其他项目可能没有战测试过这么多年。

编制时注处理

这一个是不运行时的课程,但是是一个重要的生态系统的一部分,大多数代码生成使用不需要运行时创造的。

这开始与Java5带来独立的命令行的工具过程的注释: apt, ,并开始从Java6标注处理是纳入Java编译器。

在某些时候你需要明确地通过处理器,现在有了 ServiceLoader 方法(只是添加这个文件 META-INF/services/javax.annotation.processing.Processor 到罐子)编译器可以自动检测的注释处理器。

这种方法在代码生成的有缺点的过它需要很多的工作和理解的语言不码。这API是有一点麻烦,并且作为一个插件在编译器的一个必须采取极端谨慎,以使这个代码的最大弹性和用户友好的错误信息。

最大的优点是,它可以避免的另一个依赖关系在运行时,可能避免永久代记忆丢失。和一个具有完全控制而产生的代码。

结论

2002 CGLIB定一个新的标准操纵字节提供方便。许多工具和方法学(CI、复盖范围,求等)。 我们现在都不提供或不成熟。CGLIB管理有关的超过十年;这是一个相当不错的成绩。这是快速和容易的API用于操作的操作码。

它定义的新标准的有关代码生成的,但现在不是了,因为环境和需求有所改变,因此有标准和目标。

JVM改变,将会改变,在最近和未来的Java(7/8/9/10)版本(invokedynamic的,默认的方法,价值类型等)。ASM升级他的API和内定期按照这些变化,但CGLIB和其他尚未使用它们。

虽然标注处理越来越牵引,它不是灵活的运行时代。

截至2015年, 字节哥们虽然相当新的现场 —提供的最引人注目 分运行时代。一个体面的更新速度,而且提交人有亲密的知识Java字节的代码内部。

其他提示

了Javassist

如果您需要代理,看看公共代理 - 它同时使用CGLIB和Javassit。

我更喜欢原始 ASM ,该相信则还是使用由CGLIB。这是低水平的,但文档的辉煌的,一旦你习惯了它,你将会飞。

要回答你的第二个问题,你应该在你的反射和动态代理都开始觉得有点拼凑起来的,你需要一个坚如磐石的解决方案中使用的代码生成。在过去,我甚至增加了一个代码生成步骤将在Eclipse构建过程中,有效地给我编的予取予求时间报告。

我觉得它更多的意义使用了Javassist 代替CGLIB。例如。 javasist完全不同于用CGLIB签署罐工作。此外,这种宏大的Hibernate项目决定停止支持了Javassist 使用CGLIB。

CGLIB的设计和十几年前在AOP和ORM时代实现。 目前,我看不出有任何理由使用它,我再也不会保持这个库(除了bug修复我的遗留应用程序)。 其实所有的CGLIB使用我见过的是现代的编程模式的反例。 它应该是微不足道的实施通过任何JVM脚本语言,例如相同的功能常规

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top