Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在运行时提供MapStruct映射元数据_Java_Annotations_Java Bytecode Asm_Mapstruct_Annotation Processing - Fatal编程技术网

Java 如何在运行时提供MapStruct映射元数据

Java 如何在运行时提供MapStruct映射元数据,java,annotations,java-bytecode-asm,mapstruct,annotation-processing,Java,Annotations,Java Bytecode Asm,Mapstruct,Annotation Processing,我们在业务模型和ui模型之间使用。 当UI客户端想要获得排序数据时,它可以从UI模型中指定一个字段。 我们的MapStructParser可以获得相应的业务模型字段名,并创建所需的标准对其进行排序 示例: 公共接口模型映射扩展了桥接映射{ @映射(source=“zip”,target=“plz”) UiModel modelToUiModel(业务模型,@MappingTarget UiModel UiModel); } 问题: 如何读取@映射(source=“zip”,target=“pl

我们在业务模型和ui模型之间使用。 当UI客户端想要获得排序数据时,它可以从UI模型中指定一个字段。 我们的
MapStructParser
可以获得相应的业务模型字段名,并创建所需的标准对其进行排序

示例:

公共接口模型映射扩展了桥接映射{
@映射(source=“zip”,target=“plz”)
UiModel modelToUiModel(业务模型,@MappingTarget UiModel UiModel);
}
问题:
如何读取
@映射(source=“zip”,target=“plz”)
注释并获取
源代码和
目标值?

映射
-注释具有
保留策略.CLASS
,因此无法通过反射访问它。

我们使用(字节码操作和分析框架)解决了这个问题 要阅读
映射
-注释并在元模型中提供它,请执行以下操作:

示例(也)

公共类注释解析器{
公共void解析(类映射器){
ClassInfo收集器classPrinter=新ClassInfo收集器(注释信息);
ClassReader cr=新的ClassReader(mapper.getCanonicalName());
cr.accept(classPrinter,0);
}
}
公共类ClassInfo收集器扩展ClassVisitor{
私有最终列表;
公共ClassInfo收集器(列表mapStructParser){
超级版;
this.mapStructParser=mapStructParser;
}
@凌驾
公共void访问(int版本、int访问、字符串名称、字符串签名、字符串超名、字符串[]接口){
超级访问(版本、访问、名称、签名、超级名称、接口);
}
@凌驾
public-MethodVisitor-visitMethod(int-access,String-methodName,String-descriptor,String-signature,String[]异常){
返回新的MethodInfoCollector(methodName,mapStructParser);
}
}
公共类ClassInfo收集器扩展ClassVisitor{
私有最终列表;
公共ClassInfo收集器(列表mapStructParser){
超级版;
this.mapStructParser=mapStructParser;
}
@凌驾
公共void访问(int版本、int访问、字符串名称、字符串签名、字符串超名、字符串[]接口){
超级访问(版本、访问、名称、签名、超级名称、接口);
}
@凌驾
public-MethodVisitor-visitMethod(int-access,String-methodName,String-descriptor,String-signature,String[]异常){
返回新的MethodInfoCollector(methodName,mapStructParser);
}
}
类MethodInfoCollector扩展了MethodVisitor{
私有最终字符串methodName;
私有最终列表;
public MethodInfoCollector(字符串方法,列表mapStructParser){
超级版;
this.methodName=方法;
this.mapStructParser=mapStructParser;
}
@凌驾
公共注释访问者访问注释(字符串描述符,布尔可见){
返回新的MethodAnnotationInfoCollector(methodName、descriptor、mapStructParser);
}
}
类方法AnnotationInfo收集器扩展AnnotationVisitor{
私有最终字符串方法;
私有最终字符串注释类型;
私有最终列表;
public MethodAnnotationInfo收集器(String方法、String annotationType、List mapStructParser){
超级版;
这个方法=方法;
this.annotationType=annotationType;
this.mapStructParser=mapStructParser;
}
@凌驾
公共无效访问(字符串名称、对象值){
MethodAnnotationInfo annotationInfo=新方法annotationInfo(方法、annotationType、名称、值.toString());
添加(注释信息);
超级访问(名称、值);
}
}
通过此
AnnotationParser
可以通过以下方式获取映射信息:

class业务模型{
拉链;
}
类UIM模型{
字符串plz;
}
公共接口模型映射扩展了桥接映射{
@映射(source=“zip”,target=“plz”)
UiModel modelToUiModel(业务模型,@MappingTarget UiModel UiModel);
}
@试验
公共testMappingInfo(){
MapStructParser mappingInfo=新建MapStructParser();
parseMappingInterface(ModelMapping.class);
assertEquals(“zip”,mappingInfo.mapToTargetField(“plz”);
}
mappingInfo.mapToTargetField(“plz”)
返回
BusinessModel
zip
)的映射字段。
AnnotationParser
是一个通用的注释解析器,它提供了
MethodAnnotationInfo
的列表
MapStructParser
使用
AnnotationParser
模型通过收集
Mapping
注释来构建
MapStructMappingInfo

完整的可运行和测试示例可在以下位置获得:

从理论上讲,也可以连接到MapStruct注释处理过程并生成元模型Java类(
ModelElementProcessor
)。但我没能让它工作。添加额外的注释处理器不是直截了当的,在类编译期间调试注释处理非常麻烦。四、我们的目的是使用ASM方式,一个简单的映射就足够了


我已经做了编辑,但仅供参考,[java字节码asm]是java字节码的标记,而不是[assembly]。我还建议添加[java]标记,但这需要删除另一个标记。