• 掉干BeanUtil!把Bean自动映射了神器出Spring插件!


    安利通过Mapstruct这个神器,它可以代替BeanUtil进行DTOVOPO之间的转换。它使用的是 Java 编译期的注释处理器机制,说白了它是一个代码生成器,而不是你手动进行类型转换期间的取值操作。

    它给项目都使用了很多新鲜的代码,之前发现了很多鱼的时间,用过的好。

    1. @Mapper(componentModel = "spring")
    2. public interface AreaMapping {
    3. List<AreaInfoListVO> toVos(List<Area> areas);
    4. }

    就这么几行把一个PO的集合变成了VO的集合。

    1. // spring bean
    2. @Autowired
    3. AreaMapping areaMapping
    4. // 转换源 areas
    5. List<Area> areas = ……;
    6. // 转换目标 vos
    7. List<AreaInfoListVO> vos = areaMapping.toVos(areas)

    换成你手写,起码得五分炷香的尝试。

    这样写还是爽,每次都要挂的Mapper类。

    转换器

    Spring框架提供了一个Converter<S,T>接口:

    1. @FunctionalInterface
    2. public interface Converter<S, T> {
    3. @Nullable
    4. T convert(S source);
    5. default <U> Converter<S, U> andThen(Converter<? super T, ? extends U> after) {
    6. Assert.notNull(after, "After Converter must not be null");
    7. return (s) -> {
    8. T initialResult = this.convert(s);
    9. return initialResult != null ? after.convert(initialResult) : null;
    10. };
    11. }
    12. }

    它的作用而转换为,这和 MapstructS作用不谋而合。T

    Converter会通过ConverterRegistry这个注册接口注册到ConversionService,然后你就可以通过什么ConversionService方法convert来进行转换:

    <T> T convert(@Nullable Object source, Class<T> targetType);

    MapStruct Spring 扩展

    根据各项机制官方推出的Spring Extensions插件,它的自动映射结构映射接口(Mapper)实现了,我们只需要通过Map 实现全部Converter到任何转换操作即可。ConversionServiceConversionService

    1. /**
    2. * @author felord.cn
    3. * @since 1.0.0
    4. */
    5. @Mapper(componentModel = "spring")
    6. public interface CarMapper extends Converter<Car, CarDto> {
    7. @Mapping(target = "seats", source = "seatConfiguration")
    8. CarDto convert(Car car);
    9. }

    调用时:

    1. @Autowired
    2. private ConversionService conversionService;
    3. Car car = ……;
    4. CarDto carDto = conversionService.convert(car,CarDto.class);

    MapStructs会自动生成一个类型的处理Mapper注册:

    1. package org.mapstruct.extensions.spring.converter;
    2. import cn.felord.mapstruct.entity.Car;
    3. import cn.felord.mapstruct.entity.CarDto;
    4. import org.springframework.context.annotation.Lazy;
    5. import org.springframework.core.convert.ConversionService;
    6. import org.springframework.stereotype.Component;
    7. /**
    8. * @author felord.cn
    9. * @since 1.0.0
    10. */
    11. @Component
    12. public class ConversionServiceAdapter {
    13. private final ConversionService conversionService;
    14. public ConversionServiceAdapter(@Lazy final ConversionService conversionService) {
    15. this.conversionService = conversionService;
    16. }
    17. public CarDto mapCarToCarDto(final Car source) {
    18. return (CarDto)this.conversionService.convert(source, CarDto.class);
    19. }
    20. }

    自定义

    自定义名称的包名和名称

    在这种情况下,如果你希望包的类型将在org.mapstruct.extensions.spring.converter中,名称固定为。ConversionServiceAdapter

    1. package cn.felord.mapstruct.config;
    2. import org.mapstruct.MapperConfig;
    3. import org.mapstruct.extensions.spring.SpringMapperConfig;
    4. /**
    5. * @author felord.cn
    6. * @since 1.0.0
    7. */
    8. @MapperConfig(componentModel = "spring")
    9. @SpringMapperConfig(conversionServiceAdapterPackage = "cn.felord.mapstruct.config",
    10. conversionServiceAdapterClassName = "MapStructConversionServiceAdapter")
    11. public class MapperSpringConfig {
    12. }

    不指定conversionServiceAdapterPackage元素,所以的 Adapter 类将注释的配置与生成相同的一个包中,上面的路径是可以这样的。

    指定转换服务

    如果你的Spring IoC包含多个参数ConversionService,你可以通过@SpringMapperConfig注解的conversionServiceBeanName指定。

    1. package cn.felord.mapstruct.config;
    2. import org.mapstruct.MapperConfig;
    3. import org.mapstruct.extensions.spring.SpringMapperConfig;
    4. /**
    5. * @author felord.cn
    6. * @since 1.0.0
    7. */
    8. @MapperConfig(componentModel = "spring")
    9. @SpringMapperConfig(conversionServiceAdapterPackage = "cn.felord.mapstruct.config",
    10. conversionServiceAdapterClassName = "MapStructConversionServiceAdapter",
    11. conversionServiceBeanName = "myConversionService")
    12. public class MapperSpringConfig {
    13. }

    集成Spring的编译转换

    Spring提供了很多好用的实现,内部Converter<S,T>没有直接开放,如果你想用Mapstruct的机制使用它们,可以通过@SpringMapperConfig注解externalConversions注册它们。

    1. @MapperConfig(componentModel = "spring")
    2. @SpringMapperConfig(
    3. externalConversions = @ExternalConversion(sourceType = String.class, targetType = Locale.class))
    4. public interface MapstructConfig {}

    会在中自动生成相应的转换

    1. @Component
    2. public class ConversionServiceAdapter {
    3. private final ConversionService conversionService;
    4. public ConversionServiceAdapter(@Lazy final ConversionService conversionService) {
    5. this.conversionService = conversionService;
    6. }
    7. public Locale mapStringToLocale(final String source) {
    8. return conversionService.convert(source, Locale.class);
    9. }
    10. }

    总结

    它的mapstruct-spring-annotations开发人员通过ConversionService使用定义的Mapstruct映射器,而必须允许单独导入每个Mapper,并引导Mapper之间的松散连接。它本身不会影响Mapstruct的机制。

  • 相关阅读:
    设计模式之十:状态模式
    操作符(operator)
    海康VisionMaster与西门子Smart 200进行S7通信
    权限控制、Spring Security入门
    R函数optim()最小化或者最大化多参数函数
    PMP_强化练习题(一)180题(附答案及解析)
    博物馆预约管理系统的设计与实现(论文+源码)_kaic
    【leaflet】学习笔记5 自定义控制层、多图层及其控制 && 重构
    docker 第二次学习笔记
    Log4j 漏洞还没忙完,新的漏洞又出现了
  • 原文地址:https://blog.csdn.net/m0_67698950/article/details/125529438