我正在尝试使用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,它被注入,但无法让它工作。还有什么我需要设置/配置的吗?
1条答案
按热度按时间tyu7yeag1#
因此
AnnotationsTransformerBuildItem
用于修改给定Quarkus组件使用的类的内部模型。它不会修改字节码或类似的东西,因此您无法直接观察更改,只能间接观察(通过更改的行为)。有两个类名为
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个问题:1.您错误地使用了转换API。向从
MethodInfo
返回的注解集添加注解不应该起作用,而且也不会起作用。转换API基本上是一个回调。对于任何给定的元素,都会使用TransformationContext
调用,并且必须通过TransformationContext
修改注解。由于您试图修改io.quarkus.redis.datasource.value.ValueCommands
方法上的注解,因此您的appliesTo
方法应该是return kind == AnnotationTarget.Kind.METHOD
,而transform
方法应该检查它给出的方法是否在您需要的类上声明。1.但是,即使您正确地使用了转换API,它仍然无法工作。您正在尝试修改
io.quarkus.redis.datasource.value.ValueCommands
上的注解,这是一个接口。接口永远不是bean类,CDI也永远不会从接口继承注解,所以这样的转换是无用的。1.即使您找到了
ValueCommands
的具体实现,它仍然无法工作。只有当类是CDI * 托管bean*(也称为基于类的bean)时,才有意义向类添加拦截器绑定。Redis客户端暴露的大多数API根本不是CDI bean,而那些是(例如您可以注入的RedisDataSource
)不是托管bean(它们实际上是合成bean)。所以这些都不能被拦截。总而言之,确保Redis调用被正确跟踪是不可能使用注解转换的。
好消息是,底层的Vert.x Redis客户端实现在4.4.5版本中获得了对跟踪的原生支持。Quarkus从3.4版本(几天前发布)开始使用这个版本,所以它应该在升级后开箱即用,或者在Quarkus端实现应该相当简单。如果Redis命令跟踪不适用于Quarkus 3.4,请提交功能请求。