<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          類型轉(zhuǎn)換神器Mapstruct新出的Spring插件真好用

          共 641字,需瀏覽 2分鐘

           ·

          2022-05-10 23:30

          胖哥在幾年前安利過Mapstruct這個(gè)神器,它可以代替BeanUtil來進(jìn)行DTO、VO、PO之間的轉(zhuǎn)換。它使用的是Java編譯期的 ?annotation processor 機(jī)制,說白了它就是一個(gè)代碼生成器,代替你手工進(jìn)行類型轉(zhuǎn)換期間的取值賦值操作。

          胖哥很多項(xiàng)目都使用了它,代碼清爽得很,增加了大量摸魚時(shí)間,用過的都說好。

          @Mapper(componentModel?=?"spring")
          public?interface?AreaMapping?{

          ????List?toVos(List?areas);
          }

          就這么幾行就把一個(gè)PO的集合轉(zhuǎn)換成了對應(yīng)VO的集合。

          //?spring?bean?
          @Autowired
          AreaMapping?areaMapping
          ????
          //?轉(zhuǎn)換源?areas????
          List?areas?=?……;
          //?轉(zhuǎn)換目標(biāo)?vos?
          List?vos?=?areaMapping.toVos(areas)

          換成你手寫試試,起碼得五分之一炷香的功夫。

          但是這樣寫還是不太爽,每次都要掛對應(yīng)的Mapper類。

          Converter

          Spring framework提供了一個(gè)Converter接口:

          @FunctionalInterface
          public?interface?Converter<S,?T>?{
          ????@Nullable
          ????T?convert(S?source);

          ????default??Converter?andThen(Convertersuper?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轉(zhuǎn)換為T,這和Mapstruct的作用不謀而合。

          Converter會通過ConverterRegistry這個(gè)注冊接口注冊到ConversionService,然后你就可以通過ConversionServiceconvert方法來進(jìn)行轉(zhuǎn)換:

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

          MapStruct Spring Extensions

          根據(jù)上面的機(jī)制官方推出了MapStruct Spring Extensions插件, 它實(shí)現(xiàn)了一種機(jī)制,所有的Mapstruct映射接口(Mapper)只要實(shí)現(xiàn)了Converter,都會自動(dòng)注冊到ConversionService,我們只需要通過ConversionService就能完成任何轉(zhuǎn)換操作。

          /**
          ?*?@author?felord.cn
          ?*?@since?1.0.0
          ?*/

          @Mapper(componentModel?=?"spring")
          public?interface?CarMapper?extends?Converter<Car,?CarDto>?{

          ????@Mapping(target?=?"seats",?source?=?"seatConfiguration")
          ????CarDto?convert(Car?car);
          }

          調(diào)用時(shí):

          @Autowired
          private?ConversionService?conversionService;

          Car?car?=?……;
          CarDto?carDto?=?conversionService.convert(car,CarDto.class);

          MapStruct Spring Extensions?會自動(dòng)生成一個(gè)適配類處理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);
          ????}
          }

          自定義

          自定義適配類的包路徑和名稱

          默認(rèn)情況下,生成的適配類將位于包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 駐留在同一個(gè)包中,所以上面的路徑是可以省略的。

          指定ConversionService

          如果你的Spring IoC容器中有多個(gè)ConversionService,你可以通過@SpringMapperConfig注解的conversionServiceBeanName?參數(shù)指定。

          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的內(nèi)置轉(zhuǎn)換

          Spring內(nèi)部提供了很多好用的Converter實(shí)現(xiàn),有的并不直接開放,如果你想用Mapstruct的機(jī)制使用它們,可以通過@SpringMapperConfig注解的?externalConversions注冊它們。

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

          會在適配器中自動(dòng)生成相應(yīng)的轉(zhuǎn)換:

          @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);
          ??}
          }

          總結(jié)

          mapstruct-spring-annotations?使開發(fā)人員能夠通過ConversionService使用定義的?Mapstruct?映射器,而不必單獨(dú)導(dǎo)入每個(gè)?Mapper,從而允許?Mapper?之間的松散耦合。,它本身不會影響Mapstruct的機(jī)制。相關(guān)的DEMO可以通過公眾號回復(fù) mapstructspring 獲取。


          往期推薦

          IntelliJ IDEA 卡成球了?


          知網(wǎng)哭窮賠不起1200億,網(wǎng)友:收錢時(shí)咋不嫌多


          用了Stream后,代碼反而越寫越丑?




          有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)

          歡迎大家關(guān)注Java之道公眾號


          好文章,我在看??

          瀏覽 30
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  波多野结衣一区二区三区免费视频 | 影音先锋男人站资源 | 国产久久福利导航 | A黄色视频| 亚洲激情片|