Dozer 5.2.0映射继承类时自定义转换器调用异常问题
解决Dozer 5.2.0中子类转换器未被优先调用的问题
这个问题我之前也碰到过,Dozer 5.2.0的转换器匹配逻辑确实会出现这种父类转换器“抢”了子类转换器的情况,具体原因和解决办法如下:
问题根源
Dozer在查找匹配的转换器时,默认会按照**“宽泛匹配”**的逻辑遍历配置的转换器列表:只要源对象是class-a的实例(包括子类)、目标对象是class-b的实例(包括子类),就会使用该转换器。因为B是A的子类,所以当你先配置了A-C的转换器时,Dozer会先匹配到这个宽泛的父类转换器,而不会继续往后找更精确的B-C转换器。
解决方案
1. 调整转换器的配置顺序(最简单的办法)
把子类的转换器配置放在父类转换器的前面,因为Dozer是按配置的先后顺序查找转换器的,先找到符合条件的就会直接使用。这样当转换B到C时,会先匹配到BDozerConvertor,而不会走到ADozerConvertor。
修改后的配置如下:
<!-- 先配置子类B的转换器 --> <converter type="BDozerConvertor"> <class-a>B</class-a> <class-b>C</class-b> </converter> <!-- 再配置父类A的转换器 --> <converter type="ADozerConvertor"> <class-a>A</class-a> <class-b>C</class-b> </converter>
2. 重写转换器的isApplicable方法(更严谨的控制)
如果调整顺序后还是有问题,或者你想要更精确地控制转换器的适用范围,可以在自定义转换器中重写isApplicable方法,明确指定该转换器只处理精确的类型匹配,拒绝父类/子类的宽泛匹配。
以BDozerConvertor为例:
public class BDozerConvertor extends DozerConverter<B, C> { // 构造方法指定精确的源类型和目标类型 public BDozerConvertor() { super(B.class, C.class); } // 重写isApplicable,只匹配精确的B->C转换 @Override public boolean isApplicable(Object source, Object destination, Class<?> sourceClass, Class<?> destClass) { return sourceClass == B.class && destClass == C.class; } // 实现具体的转换逻辑 @Override public C convertTo(B source, C destination) { // 你的B转C逻辑 return destination; } @Override public B convertFrom(C source, B destination) { // 你的C转B逻辑 return destination; } }
这样配置后,BDozerConvertor只会处理B类型到C类型的精确转换,不会再被父类类型的转换触发,同时ADozerConvertor依然可以处理A类型(非B子类的A实例)到C的转换。
内容的提问来源于stack exchange,提问作者Dorin
相关产品推荐
相关产品推荐

