我正在尝试使用 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中annotation
和annotateParameter
的区别。前者注解类型,另一个注解参数。这可能看起来令人困惑,因为语法不明确:
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/