java - 如何向 Bytebuddy 中的新方法添加动态数量的带注释参数?

标签 java byte-buddy

我正在尝试使用 ByteBuddy 在运行时创建许多类。到目前为止,我已经设法创建类、添加方法并对其进行注释。这是一个很棒的工具,到目前为止我一直很喜欢使用它。

但现在我卡住了。我有我的类(class),有一个方法并且有 n 个参数(由配置动态控制)。这有点像......

DynamicType.Builder<?> builder = new ByteBuddy().subclass(Object.class)
                                .name(newClassName)
                                .annotateType(AnnotationDescription.Builder.ofType(Controller.class).build());

// loop for all methods to create
for (final MethodDefinition methodDefinition : methodDefinitions) {

    final List<TypeDefinition> parameters = new ArrayList<>();

    for (final MethodParameterDefinition methodParamDef : methodDefinition.getMethodParameterDefinitions()) {
        parameters.add( TypeDescription.Generic.Builder.rawType(methodParamDef.getType()).build() );
    }

    // define the method
    builder = builder
        .defineMethod(methodDefinition.getName(), outputValueObjectClass, Modifier.PUBLIC)
        .withParameters(parameters)                            
        .annotateMethod(AnnotationDescription.Builder.ofType(RequestMapping.class)
            .defineEnumerationArray("method", RequestMethod.class, RequestMethod.valueOf(methodDefinition.getHttpMethod()))
            .defineArray("path", methodDefinition.getUrl()).build())
        .annotateMethod(AnnotationDescription.Builder.ofType(ResponseBody.class).build())
}

final DynamicType.Unloaded unloadedClass = builder.make();

但是当我尝试使用以下代码向其中一个参数添加注释时...

for (final MethodParameterDefinition methodParamDef : methodDefinition.getMethodParameterDefinitions()) {
    parameters.add( TypeDescription.Generic.Builder.rawType(methodParamDef.getType())
        .annotate(AnnotationDescription.Builder.ofType(PathVariable.class).define("name", methodParamDef.getName()).build())
        .build() );
}

...我得到以下异常....

java.lang.IllegalStateException: Illegal type annotations return type class... 

如果我知道方法参数的数量,我可以使用如下代码添加这些参数...

builder = builder
    .defineMethod(methodDefinition.getName(), outputValueObjectClass, Modifier.PUBLIC)
    .withParameter(methodParameterClass).annotateParameter(AnnotationDescription.Builder.ofType(ModelAttribute.class).build())
    .annotateMethod(AnnotationDescription.Builder.ofType(RequestMapping.class)
        .defineEnumerationArray("method", RequestMethod.class, RequestMethod.valueOf(methodDefinition.getHttpMethod()))
        .defineArray("path", methodDefinition.getUrl()).build())
    .annotateMethod(AnnotationDescription.Builder.ofType(ResponseBody.class).build())

但这不适用于动态方法。

有谁知道如何向方法添加动态数量的参数(带注释)?

提前致谢!

最佳答案

我刚刚检查了代码,由于复制粘贴错误,异常消息具有误导性。错误消息应该告诉您您正在使用不是类型注释的注释来注释类型。

注意代码生成DSL中annotationannotateParameter的区别。前者注解类型,另一个注解参数。这可能看起来令人困惑,因为语法不明确:

void foo(@Bar List<?> qux) { ... }

在Java中可以表示两者,如果@Bar是类型注解,则注解List类型,如果是参数注解,则注解参数qux,如果是both,类型和参数都会被注解。在字节码级别上,您可以选择要注释的元素。但是由于您的注释仅与参数兼容,因此显示了(误导性的,现在已在 master 上修复)错误消息。

如果要添加动态数量的参数,只需在 DynamicType.Builder 上运行循环并添加如下参数:

MethodDefinition.ParameterDefinition builder = ...
for (...) {
  builder = builder.withParameter(...).annotateParameter(...);
}

这应该可以解决问题。

关于java - 如何向 Bytebuddy 中的新方法添加动态数量的带注释参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51444763/

相关文章:

java - Byte Buddy 将 Try block 添加到现有方法中

java - Java 简单日期格式的问题

java - 如何根据主键的值更改外键?

java - 带 TitledBorder 的面板中的渐变文本字段 - 性能问题

java - 在 Byte Buddy 中缓存生成的类?

java - 使用 ByteBuddy : "class redefinition failed: attempted to add a method" 重新定义方法时出错

java - 如何在 ByteBuddy 转换期间增加方法?

java - 是否可以使用 Firebase Admin SDK 将消息发送到 FCM 客户端的一批 token ?

java - 使用 spring mvc 安排任务