gpt4 book ai didi

java - 如何在运行时提供 MapStruct Mapping 注解映射元数据

转载 作者:行者123 更新时间:2023-12-04 09:34:12 27 4
gpt4 key购买 nike

我们使用 MapStruct在商业模型和我们的用户界面模型之间。
当 UI 客户端想要获取排序数据时,它可以从 ui-model 中指定一个字段。
我们的 MapStructParser可以获取相应的业务模型字段名称并创建所需的 Criteria 对其进行排序。
示例:

public interface ModelMapping extends BridgeMapping<BusinessModel, UiModel> {
@Mapping(source = "zip", target = "plz")
UiModel modelToUiModel(BusinessModel model, @MappingTarget UiModel uiModel);
}
问题:
如何阅读 @Mapping(source = "zip", target = "plz")注释并获得 sourcetarget值(value)? Mapping -注解有 RetentionPolicy.CLASS ,因此无法通过反射访问它。

最佳答案

我们通过使用 ASM 解决了这个问题(字节码操作和分析框架)
阅读 Mapping -注释并在元模型中提供它:
示例 (还有 available on Github )

public class AnnotationParser {
public void parse(Class<?> mapper) {
ClassInfoCollector classPrinter = new ClassInfoCollector(annotationInfos);
ClassReader cr = new ClassReader(mapper.getCanonicalName());
cr.accept(classPrinter, 0);
}
}

public class ClassInfoCollector extends ClassVisitor {

private final List<MethodAnnotationInfo> mapStructParser;

public ClassInfoCollector(List<MethodAnnotationInfo> mapStructParser) {
super(ASMversion);
this.mapStructParser = mapStructParser;
}

@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
}

@Override
public MethodVisitor visitMethod(int access, String methodName, String descriptor, String signature, String[] exceptions) {
return new MethodInfoCollector(methodName, mapStructParser);
}

}

public class ClassInfoCollector extends ClassVisitor {

private final List<MethodAnnotationInfo> mapStructParser;

public ClassInfoCollector(List<MethodAnnotationInfo> mapStructParser) {
super(ASMversion);
this.mapStructParser = mapStructParser;
}

@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
}

@Override
public MethodVisitor visitMethod(int access, String methodName, String descriptor, String signature, String[] exceptions) {
return new MethodInfoCollector(methodName, mapStructParser);
}

}

class MethodInfoCollector extends MethodVisitor {

private final String methodName;
private final List<MethodAnnotationInfo> mapStructParser;

public MethodInfoCollector(String method, List<MethodAnnotationInfo> mapStructParser) {
super(ASMversion);
this.methodName = method;
this.mapStructParser = mapStructParser;
}

@Override
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
return new MethodAnnotationInfoCollector(methodName, descriptor, mapStructParser);
}
}

class MethodAnnotationInfoCollector extends AnnotationVisitor {

private final String method;
private final String annotationType;
private final List<MethodAnnotationInfo> mapStructParser;

public MethodAnnotationInfoCollector(String method, String annotationType, List<MethodAnnotationInfo> mapStructParser) {
super(ASMversion);
this.method = method;
this.annotationType = annotationType;
this.mapStructParser = mapStructParser;
}

@Override
public void visit(String name, Object value) {
MethodAnnotationInfo annotationInfo = new MethodAnnotationInfo(method, annotationType, name, value.toString());
mapStructParser.add(annotationInfo);
super.visit(name, value);
}

}
机智的 AnnotationParser可以通过这种方式获取映射信息:
class BusinessModel{
String zip;
}

class UiModel{
String plz;
}

public interface ModelMapping extends BridgeMapping<BusinessModel, UiModel> {
@Mapping(source = "zip", target = "plz")
UiModel modelToUiModel(BusinessModel model, @MappingTarget UiModel uiModel);
}

@Test
public testMappingInfo(){
MapStructParser mappingInfo = new MapStructParser();
mappingInfo.parseMappingInterface(ModelMapping.class);
assertEquals("zip", mappingInfo.mapToTargetField("plz"));
}
mappingInfo.mapToTargetField("plz")返回 if BusinessModel 的映射字段( zip )。 AnnotationParser是一个通用的注释解析器,它提供了 MethodAnnotationInfo 的列表. MapStructParser使用 AnnotationParser模型搭建 MapStructMappingInfo通过收集 Mapping - 注释。
完整的可运行和经过测试的示例可在此处获得:
https://github.com/TobseF/mapstruct-metadata-example

Theoretically it also possible to hook into the MapStruct annotation processing process and generate MetaModel Java classes (ModelElementProcessor). But I wasn't able to get it working. Adding additional Annotation processors is't straight forward and debugging Annotation processing during class compilation is more than cumbersome. Four our purpose the ASM way and a simple mapping is sufficient.

关于java - 如何在运行时提供 MapStruct Mapping 注解映射元数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62675889/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com