1. 概述
在这篇文章中,我们将探讨Quarkus与经典Jakarta EE环境中的bean发现的区别。我们将重点关注如何确保Quarkus在外部模块中能够发现注解类。
2. 为何Quarkus需要索引
Quarkus的一个主要优势是其极快的启动时间。为了实现这一点,Quarkus将类路径注解扫描等步骤从运行时提前到了构建时。因此,我们需要在构建时声明所有依赖。
这意味着在运行环境中通过类路径扩展增强应用程序已不再可能。当在构建期间收集元数据时,索引就发挥作用了。索引意味着将元数据存储在一个索引文件中。这样,应用程序可以在启动时或需要时快速读取它。
让我们通过一个简单的示例来说明区别:
Quarkus使用Jandex来创建和读取索引。
3. 创建索引
对于我们的Quarkus项目中的类,我们不需要做特别的事情——Quarkus Maven插件会自动生成索引。但我们需要关注依赖项,包括项目内部模块和外部库。
3.1. Jandex Maven插件
对于自定义模块,最直接的方法是使用Jandex Maven插件:
<build>
<plugins>
<plugin>
<!-- https://github.com/wildfly/jandex-maven-plugin -->
<groupId>org.jboss.jandex</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>make-index</id>
<goals>
<!-- phase is 'process-classes by default' -->
<goal>jandex</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
这个插件会在打包的JAR中生成一个META-INF/jandex.idx
文件。当运行时提供该文件时,Quarkus会读取它。因此,每个包含此类文件的库都默认增强了索引。
对于Gradle构建,我们可以使用org.kordamp.gradle.jandex
插件:
plugins {
id 'org.kordamp.gradle.jandex' version '0.11.0'
}
3.2. 应用程序属性
如果我们无法修改依赖(例如外部库的情况下),我们需要在Quarkus项目的application.properties
文件中显式指定它们:
quarkus.index-dependency.<name>.group-id=<groupId> quarkus.index-dependency.<name>.artifact-id=<artifactId> quarkus.index-dependency.<name>.classifier=(可选)
3.3. 框架规定的含义
如果不使用Jandex Maven插件,模块也可以包含一个META-INF/beans.xml
文件。这实际上是被Quarkus采用并进行了一些调整的CDI技术的一部分,但我们不必仅限于使用CDI管理的bean。我们也可以声明例如JAX-RS资源,因为索引的范围是整个模块。
4. 总结
本文确定了Quarkus在运行时需要Jandex索引来检测注解类。索引在构建时生成,因此标准技术无法检测构建后添加到类路径中的注解类。
一如既往,所有的代码都可以在GitHub上找到,那里有一个包含Quarkus应用和一些提供CDI管理bean的多模块项目。