传统痛点在哪里?
对于分布式系统,需要在不同系统之间传递与转换域对象。因为我们不希望外部公开内部域对象,也不允许外部域对象渗入系统。
传统上,数据对象之间的映射通过手工编码(getter/setter)的方式实现,或对象组装器(或转换器)来解决,代码繁琐。
Dozer 是什么?
Dozer 是 Java Bean 到 Java Bean 映射器,它以递归方式将数据从一个对象复制到另一个对象。
通常,这些 Java Bean 将具有不同的复杂类型。Dozer 支持简单属性映射,复杂类型映射,双向映射,隐式和显式映射以及递归映射。
Dozer还不仅支持属性名称之间的映射,还支持在类型之间自动转换(大多数转换方案都是开箱即用的),且 Dozer 还允许您通过 XML / API 的方式指定自定义转换。
Dozer通常可以插入到架构中的边界(进入/退出)
Dozer 怎样集成?
一、环境配置
1、Maven工程中pom.xml增加依赖
<dependency>
<groupId>com.github.dozermapper</groupId>
<artifactId>dozer-core</artifactId>
<version>6.4.0</version>
</dependency>
1、使用SpringBoot 需引入dozer-spring-boot-starter依赖
<dependency>
<groupId>com.github.dozermapper</groupId>
<artifactId>dozer-spring-boot-starter</artifactId>
<version>6.2.0</version>
</dependency>
二、默认使用
1、dozer-spring-boot-starter默认为我们注入了 Dozer Mapper,可以直接使用。注意导包
import org.dozer.Mapper;
@Autowired
private Mapper dozerMapper;
2、通过dozerMapper.map方法实现对象到对象之间属性名称一致的映射(默认支持同名 field 的双向映射,即隐式映射)
XxxVo studentVo = dozerMapper.map(XxxDomain, XxxVo.class);
三、自定义Mapper使用
1、新建 DozerConfig.java 类
@Configuration
public class DozerConfig {
@Bean
public Mapper dozerMapper(){
Mapper mapper = DozerBeanMapperBuilder.create()
.withMappingFiles("dozerBeanMapping.xml")
.withMappingBuilder(beanMappingBuilder())
.build();
return mapper;
}
@Bean
public BeanMappingBuilder beanMappingBuilder() {
return new BeanMappingBuilder() {
@Override
protected void configure() {
mapping(XxxDomain.class, XxxVo.class)
.exclude("xfield2")
.fields("xxxdx[0].xxxdxfield", "xfield");
}
};
}
}
注意:隐式递归匹配所有 field(包括对象),甚至集合
通过深度匹配指定字段,匹配方式以 "." 号进行分割,集合属性可以指定索引
Dozer 开箱即用的功能之一就是类型转换,多数类型我们不需要手动转换类型,完全交给 Dozer即可。
部分不可以类型转换。比如:Date 和 String 不可以,我们需要指定 date-formate 格式。
设置了全局/类/Field 级别的 date-format,按照优先级最高的进行格式化:Field > 类 > 全局
全局设置,修改 dozerBeanMapping.xml
mapper()方法增加参数 TypeMappingOptions.dateFormat("yyyy-MM-dd")
当有些字段需要特殊处理的时候,我们需要实现自定义转换,也就是需要自定义 Converter,继承 DozerConverter<A, B>, 并实现其方法
Dozer 可以通过实现 DozerEventListener 接口实现 mapping 的事件监听,在 mapping 的时候做全局业务