我正在考虑使用注释处理器在编译时为使用某种注释类型注释的类构建索引(甚至是存储在文件中的简单列表),以加快运行时带注释的类检索速度。
那么,这是一个好的做法吗?有什么缺点吗?如果它像我现在看起来的那样好,为什么没有很多库以简单的方式做到这一点(我找到的唯一一个是Class Index)?而不是运行时处理有这么多?
作为 ClassIndex 库的作者,我可以列出使用注释处理进行注释索引的几个优点,但也列出了我认为阻碍其广泛采用的缺点。
优点:
缺点:
JBoss WildFly 的一个子项目,您可能会感兴趣:Jandex。
它在构建时(并且索引文件可以添加到 JAR 中)或运行时(通过检查类文件而不是通过反射来检索注释)创建注释索引,显着提高注释检索的性能,因为它避免了实际加载类的需要.
Jandex 听起来很像你想要的。
我认为主要缺点是比较复杂。注解处理是一个全新的 API 和概念,许多开发人员并不熟悉。 Reflection API 更简单,也更广为人知。您通常可以在运行时完成相同的任务。
如果更好的启动性能至关重要(这种情况很少发生),那么增加复杂性也许是值得的。
不过我不相信这些基准。他们声明“类路径大小设置为 121MB”——这是一个任意值,使得与硬编码或编译时处理的任何比较都完全无用。无论如何你为什么要扫描整个类路径?在大多数情况下,仅扫描开发人员类会更合理。
许多框架使用配置文件或具有API来限制需要扫描的类或包。这会显着增加启动时间。
为什么没有很多图书馆可以做到这一点
许多 OSGi 工具/框架都这样做。在编译时扫描注释,并将元数据写入 jar 清单文件,或者创建更复杂的元数据文件。我怀疑这样做的主要原因是为了保持与 bnd 和类似工具的兼容性,在注释或注释处理变得更流行之前,这些工具已被用于构建和编译 OSGi 组件的时间分析。此外,OSGi 组件有自己的生命周期,可以随时出现和消失。因此,在这种情况下,启动时间确实更重要,因为您不能只在应用程序启动时扫描一次。每当组件(重新)启动时,您都需要扫描注释。
我不会说这是一个好或坏的做法。当它适合您的需要时使用此技术。我会避免为了几毫秒的启动时间而增加太多的复杂性。
SezPoz 使用注释处理器为此提供了一个固执己见且易于使用的界面。 Sławek 提到的注意事项适用。