我正在尝试使用 BuildStep 转换注释数据,如下面的链接所述
https://quarkus.io/guides/cdi-integration#annotations_transformer_build_item
但是,我没有看到任何迹象表明这有效。我无法在构建期间验证出了什么问题,并且在运行时没有发生任何变化。以下是示例代码:
public class TestTelemetryBuilder {
@BuildStep
AnnotationsTransformerBuildItem transform() {
return new AnnotationsTransformerBuildItem(new AnnotationsTransformer() {
@Override
public boolean appliesTo(final org.jboss.jandex.AnnotationTarget.Kind kind) {
return kind == org.jboss.jandex.AnnotationTarget.Kind.CLASS;
}
@Override
public void transform(final TransformationContext context) {
if ("io.quarkus.redis.datasource.value.ValueCommands"
.equals(context.getTarget().asClass().name().toString())) {
List<MethodInfo> methods = context.getTarget().asClass().methods();
AnnotationInstance annot = AnnotationInstance.builder(DotName.createSimple(
"io.opentelemetry.instrumentation.annotations.WithSpan")).build();
methods.forEach(t -> t.annotations()
.add(annot));
}
}
});
}
}
我想在 Redis ValueCommands 类上的所有方法被调用时添加 WithSpan 注释。这仅在注入类时才起作用吗?我尝试使用注入的 RedisDataSource 但无法使其工作。我还需要设置/配置什么吗?
因此
AnnotationsTransformerBuildItem
用于修改给定 Quarkus 组件使用的类的内部模型。它不会修改字节码或类似的内容,因此您无法直接观察到更改,只能间接地(通过更改的行为)观察到更改。
有 2 个类名为
AnnotationsTransformerBuildItem
:
io.quarkus.arc.deployment.AnnotationsTransformerBuildItem
对于 ArC,Quarkus 中的 CDI 容器io.quarkus.resteasy.reactive.server.spi.AnnotationsTransformerBuildItem
对于 RESTEasy Reactive,Quarkus 中的 JAX-RS 实现由于
@WithSpan
在 Quarkus 中被视为拦截器绑定,因此您需要 ArC 的 AnnotationsTransformerBuildItem
。
假设你有ArC的
AnnotationsTransformerBuildItem
,有3个问题:
您错误地使用了转换 API。将注释添加到从
MethodInfo
返回的注释集中不应该起作用,而且也不会起作用。转换 API 基本上是一个回调。对于任何给定元素,您都将使用 TransformationContext
进行调用,并且必须通过 TransformationContext
修改注释。由于您正在尝试修改 io.quarkus.redis.datasource.value.ValueCommands
方法上的注释,因此您的 appliesTo
方法应该是 return kind == AnnotationTarget.Kind.METHOD
并且 transform
方法应该检查它给出的方法是否在您需要的类上声明。
但是即使你正确使用了转换API,它仍然无法工作。您正在尝试修改
io.quarkus.redis.datasource.value.ValueCommands
上的注释,这是一个接口。接口永远不是bean类,CDI永远不会从接口继承注释,所以这样的转换是没有用的。
就算你找到了
ValueCommands
的具体实现,还是不行。仅当该类是 CDI 托管 bean(也称为基于类的 bean)时,向类添加拦截器绑定才有意义。 Redis 客户端公开的大多数 API 根本不是 CDI bean,而那些 CDI bean(例如可以注入的RedisDataSource
)也不是托管 bean(它们实际上是合成 bean)。所以实际上这些都不能被拦截。
总而言之,使用注释转换无法确保正确跟踪 Redis 调用。
好消息是,底层 Vert.x Redis 客户端实现已在 4.4.5 版本中获得了对跟踪的本机支持。该版本自 3.4 版(几天前发布)起就在 Quarkus 中使用,因此升级后它应该可以开箱即用,或者在 Quarkus 端实现起来应该相当简单。如果 Redis 命令跟踪不适用于 Quarkus 3.4,请提交功能请求。