Quarkus AnnotationsTransformerBuildItem未按预期工作问题求助
问题分析
你遇到的核心问题是:AnnotationsTransformerBuildItem 仅修改了CDI容器处理的元数据,但Quarkus的JAX-RS路由构建基于Jandex索引或原始类字节码,并未同步读取CDI修改后的注解。控制台打印说明Transformer逻辑触发成功,但JAX-RS的端点注册流程早于或独立于CDI的注解转换,导致修改未生效。
解决方案
方案1:调整注解转换执行时机,确保JAX-RS感知到修改
Quarkus构建步骤有严格执行顺序,需让AnnotationsTransformer在JAX-RS扫描端点前运行,同时合并注解修改操作(避免多次transform()调用导致状态覆盖)。
修改后的代码:
package com.tawfeek.greeting.extension.deployment; import io.quarkus.arc.deployment.AnnotationsTransformerBuildItem; import io.quarkus.arc.processor.AnnotationsTransformer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.annotations.Order; import io.quarkus.deployment.builditem.FeatureBuildItem; import org.jboss.jandex.AnnotationTarget; import org.jboss.jandex.DotName; import org.jboss.jandex.MethodInfo; class GreetingExtensionProcessor { private static final String FEATURE = "greeting-extension"; // 定义常量避免硬编码字符串错误 private static final DotName GET = DotName.createSimple("jakarta.ws.rs.GET"); private static final DotName POST = DotName.createSimple("jakarta.ws.rs.POST"); @BuildStep FeatureBuildItem feature() { return new FeatureBuildItem(FEATURE); } // 设置执行顺序,确保在JAX-RS端点扫描前完成注解转换 @BuildStep @Order(io.quarkus.deployment.annotations.Phase.BEFORE_ANALYSIS) AnnotationsTransformerBuildItem transformAnnotations() { return new AnnotationsTransformerBuildItem(new AnnotationsTransformer() { @Override public boolean appliesTo(AnnotationTarget.Kind kind) { return kind == AnnotationTarget.Kind.METHOD; } @Override public void transform(TransformationContext context) { MethodInfo methodInfo = context.getTarget().asMethod(); if (methodInfo.hasAnnotation(GET)) { // 合并remove和add操作到同一个transform链 context.transform() .remove(annotationInstance -> annotationInstance.name().equals(GET)) .add(POST) .done(); System.out.println("method " + methodInfo.name() + " is changed from GET to POST"); } } }); } }
关键调整点:
- 使用
@Order(Phase.BEFORE_ANALYSIS)确保注解转换在JAX-RS端点元数据收集前执行 - 将
remove和add操作合并到同一个transform()链中,避免多次done()导致的状态覆盖 - 用
DotName常量替代硬编码字符串,减少拼写错误
方案2:直接修改类字节码(更可靠的方式)
如果方案1仍不生效,说明JAX-RS完全不依赖CDI的注解转换结果,此时需要直接修改类的字节码,让JAX-RS扫描时读取到修改后的注解。
实现代码:
package com.tawfeek.greeting.extension.deployment; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.FeatureBuildItem; import io.quarkus.deployment.builditem.transformer.ClassTransformerBuildItem; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; class GreetingExtensionProcessor { private static final String FEATURE = "greeting-extension"; private static final String GET_DESC = "Ljakarta/ws/rs/GET;"; private static final String POST_DESC = "Ljakarta/ws/rs/POST;"; @BuildStep FeatureBuildItem feature() { return new FeatureBuildItem(FEATURE); } @BuildStep ClassTransformerBuildItem transformClass() { return ClassTransformerBuildItem.builder() .setClassVisitorTransformer((className, classVisitor) -> new ClassVisitor(classVisitor) { @Override public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { // 不修改类级注解,直接传递 return super.visitAnnotation(descriptor, visible); } @Override public AnnotationVisitor visitMethodAnnotation(int access, String name, String descriptor, String signature, String[] exceptions) { AnnotationVisitor av = super.visitMethodAnnotation(access, name, descriptor, signature, exceptions); return new AnnotationVisitor(av) { @Override public void visit(String name, Object value) { // 如果是@GET注解,替换为@POST if (GET_DESC.equals(descriptor)) { // 先移除原@GET注解 av.visitEnd(); // 添加@POST注解 return super.visitMethodAnnotation(access, name, POST_DESC, signature, exceptions); } super.visit(name, value); } }; } }) // 仅匹配目标包下的类(可选,优化性能) .setTargetClassPredicate(className -> className.startsWith("your.target.package")) .build(); } }
说明:
- 直接操作ASM字节码修改方法注解描述符,JAX-RS扫描类时会直接读取修改后的字节码
- 通过
setTargetClassPredicate限定转换范围,提升构建性能
验证方法
修改代码后重新构建启动应用:
- 确认控制台仍打印转换成功的日志
- 用Postman发送POST请求到原GET接口,确认返回正常;发送GET请求应返回405 Method Not Allowed
内容的提问来源于stack exchange,提问作者tawfeek shalash
相关产品推荐
相关产品推荐

