推荐这款类型转换神器!Mapstruct新出的Spring插件
Mapstruct可以代替 BeanUtil 来进行DTO 、VO 、PO 之间的转换。它使用的是Java编译期的 annotation processor 机制,说白了它就是一个代码生成器,代替你手工进行类型转换期间的取值赋值操作。
小编很多项目都使用了它,代码清爽得很,增加了大量摸鱼时间,用过的都说好。 @Mapper(componentModel = "spring") public interface AreaMapping { List toVos(List areas); }
就这么几行就把一个 PO 的集合转换成了对应 VO 的集合。 // spring bean @Autowired AreaMapping areaMapping // 转换源 areas List areas = ……; // 转换目标 vos List vos = areaMapping.toVos(areas)
换成你手写试试,起码得五分之一炷香的功夫。
但是这样写还是不太爽,每次都要挂对应的Mapper类。 Converter
Spring framework 提供了一个 Converter 接口:@FunctionalInterface public interface Converter { @Nullable T convert(S source); default Converter andThen(Converter<? super T, ? extends U> after) { Assert.notNull(after, "After Converter must not be null"); return (s) -> { T initialResult = this.convert(s); return initialResult != null ? after.convert(initialResult) : null; }; } }
它的作用是将 S 转换为T ,这和Mapstruct 的作用不谋而合。
Converter 会通过ConverterRegistry 这个注册接口注册到ConversionService ,然后你就可以通过ConversionService 的convert 方法来进行转换: T convert(@Nullable Object source, Class targetType); MapStruct Spring Extensions
根据上面的机制官方推出了 MapStruct Spring Extensions 插件, 它实现了一种机制,所有的 Mapstruct 映射接口( Mapper )只要实现了 Converter ,都会自动注册到ConversionService ,我们只需要通过ConversionService 就能完成任何转换操作。/** * @author felord.cn * @since 1.0.0 */ @Mapper(componentModel = "spring") public interface CarMapper extends Converter { @Mapping(target = "seats", source = "seatConfiguration") CarDto convert(Car car); }
调用时: @Autowired private ConversionService conversionService; Car car = ……; CarDto carDto = conversionService.convert(car,CarDto.class);
MapStruct Spring Extensions 会自动生成一个适配类处理 Mapper 注册: package org.mapstruct.extensions.spring.converter; import cn.felord.mapstruct.entity.Car; import cn.felord.mapstruct.entity.CarDto; import org.springframework.context.annotation.Lazy; import org.springframework.core.convert.ConversionService; import org.springframework.stereotype.Component; /** * @author felord.cn * @since 1.0.0 */ @Component public class ConversionServiceAdapter { private final ConversionService conversionService; public ConversionServiceAdapter(@Lazy final ConversionService conversionService) { this.conversionService = conversionService; } public CarDto mapCarToCarDto(final Car source) { return (CarDto)this.conversionService.convert(source, CarDto.class); } } 自定义自定义适配类的包路径和名称
默认情况下,生成的适配类将位于包 org.mapstruct.extensions.spring.converter 中,名称固定为ConversionServiceAdapter 。如果你希望修改包路径或者名称,你可以这样:package cn.felord.mapstruct.config; import org.mapstruct.MapperConfig; import org.mapstruct.extensions.spring.SpringMapperConfig; /** * @author felord.cn * @since 1.0.0 */ @MapperConfig(componentModel = "spring") @SpringMapperConfig(conversionServiceAdapterPackage = "cn.felord.mapstruct.config", conversionServiceAdapterClassName = "MapStructConversionServiceAdapter") public class MapperSpringConfig { }
不指定 conversionServiceAdapterPackage 元素,生成的 Adapter 类将与注解的 Config 驻留在同一个包中,所以上面的路径是可以省略的。指定ConversionService
如果你的 Spring IoC 容器中有多个 ConversionService ,你可以通过@SpringMapperConfig 注解的conversionServiceBeanName 参数指定。package cn.felord.mapstruct.config; import org.mapstruct.MapperConfig; import org.mapstruct.extensions.spring.SpringMapperConfig; /** * @author felord.cn * @since 1.0.0 */ @MapperConfig(componentModel = "spring") @SpringMapperConfig(conversionServiceAdapterPackage = "cn.felord.mapstruct.config", conversionServiceAdapterClassName = "MapStructConversionServiceAdapter", conversionServiceBeanName = "myConversionService") public class MapperSpringConfig { } 集成Spring的内置转换
Spring 内部提供了很多好用的 Converter 实现,有的并不直接开放,如果你想用Mapstruct 的机制使用它们,可以通过@SpringMapperConfig 注解的 externalConversions 注册它们。@MapperConfig(componentModel = "spring") @SpringMapperConfig( externalConversions = @ExternalConversion(sourceType = String.class, targetType = Locale.class)) public interface MapstructConfig {}
会在适配器中自动生成相应的转换: @Component public class ConversionServiceAdapter { private final ConversionService conversionService; public ConversionServiceAdapter(@Lazy final ConversionService conversionService) { this.conversionService = conversionService; } public Locale mapStringToLocale(final String source) { return conversionService.convert(source, Locale.class); } } 总结
mapstruct-spring-annotations 使开发人员能够通过 ConversionService 使用定义的 Mapstruct 映射器,而不必单独导入每个 Mapper ,从而允许 Mapper 之间的松散耦合。,它本身不会影响Mapstruct 的机制。
来源:https://mp.weixin.qq.com/s/2W4OwmSp3ZGFkvEKWQQYdw
好看又好用的手机记事本便签推荐手机记事本便签类软件是人们常用的辅助工具之一,不同的人在使用手机记事本便签软件的时候,对它的需求点是不一样的。有的人喜欢视觉效果和外观上比较出色的便签软件,有的人则更加注重便签软件
2021年学校什么时候开学?2021年已经过去一大半,随着学校的暑假接近尾声,那么接下来就是开学了。2021年秋季学校什么时候开学呢?按照惯例应该是9月1日左右开学,但是今年由于各种各样的因素影响,有些地方的
开学时间2021下半年会推迟吗?便签提醒开学时间在学生时代,每年都有两个比较长的假期,一个是寒假一个就是暑假。2021年的8月份马上就要结束了,这也就意味着学生们即将告别暑假,迎来开学。由于种种因素的影响,开学时间2021下半年
在手机端能固定在桌面的便签手机是人们使用频率比较多的一种辅助工具,在使用它的时候,可以根据自己的需求安装各式各样功能不同的软件来辅助自己。便签软件是很多人工作学习和生活中的好帮手,在使用手机端便签软件的时候
开学感想作文600字可用便签记录8月已经接近尾声了,每逢到了八月和九月交替的季节,人们都会迎来莘莘学子们的开学季。为了纪念开学对自己的深刻影响,同时也为了锻炼文字创作能力,很多人都会写开学感想作文,用便签软件辅助
苹果手机好用的记事本app这款便签告诉你苹果手机是很多人都在使用的一款电子设备,在使用它的时候,人们会在它上面安装各种各样的应用软件来获取不同的功能。对于平时事务比较多的人来说,用记事类app记录自己的待办事项是一个很好
21天养成一个好习惯用便签提醒每天要做的事人们常说,一个人在工作和学习的时候,要想有一个更好的结果,那么就有必要养成一个良好的习惯。据科学研究表明,一个习惯的养成只需要连续坚持21天就可以实现。要想在21天内养成一个好习惯
手机上简洁好用的便签app推荐智能手机现在已经走进了千家万户,和人们的工作学习和生活等等各方各面紧密的联系在了一起。在智能手机上,可以根据自己的需求来选择安装应用软件app辅助自己,便签app就是其中的一种。手
开学之际对孩子的寄语用便签写寄语更方便学生时代对于很多人来说都是比较难忘的,很多美好的记忆,都来自学生时代。2021年的秋季开学季马上就要到来了,在这个开学之际,很多长辈都会为孩子写上一段寄语,表达自己的关爱。开学之际
手机上怎样使用便签功能便签软件是很多人用过的一种辅助工具,随着科学技术的不断发展,它不但可以在电脑上使用,在手机上也可以使用。在手机上由于手机厂商的不同,具备便签功能的软件名字也不一样,有的就叫便签有的
有没有类似便签的软件app?在早些年的老电影中,经常会看到办公室的白领在忙碌的生活中,会在家中显眼的地方或是办公桌的电脑屏幕上,通过贴便签来帮助自己记事。随着科学技术的不断发展,人们有各种各样的软件app可以