亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

MapStruct Mapper 作為 Spring Framework 可以慣用使用嗎?

MapStruct Mapper 作為 Spring Framework 可以慣用使用嗎?

紅顏莎娜 2023-08-23 14:33:38
我想將MapStruct映射器與 Spring 的Conversion model結合起來。所以我將每個Mapper接口聲明為 Spring 的擴展Converter:@Mapperpublic interface CarMapper extends Converter<Car, CarDto> {        @Override    CarDto convert(Car car);    }然后我可以通過注入標準來使用映射器 bean ConversionService:class CarWarehouse {    @Autowired    private ConversionService conversionService;    ...    public CarDto getCarInformation(Car car) {        return conversionService.convert(car, CarDto.class);    }}這很好用,但我想知道是否有一種方法可以避免通過屬性直接將一些映射器注入其他映射器uses。我想做的是告訴映射器use雇用ConversionService另一個映射器。但是,由于ConversionServicesconvert方法與 MapStruct 的映射方法標準模式不匹配,因此代碼生成插件在查找子映射時無法識別它可以使用該服務?;旧希蚁胱龅氖菍慇Mapper(uses=ConversionService.class)public interface ParentMapper extends Converter<Parent, ParentDto>代替@Mapper(uses={ChildMapper1.class, ChildMapper2.class, ChildMapper3.class})public interface ParentMapper extends Converter<Parent, ParentDto>有辦法實現這一點嗎?編輯既然有人問過,假設我有一個CarMapper如上所述的定義,其類型Car和分別具有類型和的CarDto屬性。然后我希望能夠像這樣定義另一個映射器:wheelWheelWheelDto@Mapperpublic interface WheelMapper extends Converter<Wheel, WheelDto> {        @Override    WheelDto convert(Wheel wheel);    }現在,我必須顯式添加此映射器:@Mapper(uses = WheelMapper.class)public interface CarMapper extends Converter<Car, CarDto>然后,這將為生成的類型提供CarMapperImpl一個@Autowired成員WheelMapper,該成員將被調用以映射屬性wheel。然而,我想要的是生成的代碼看起來有點像這樣:@Componentpublic class CarMapperImpl implements CarMapper {    @Autowired    private ConversionService conversionService;    @Override    public CarDto convert(Car car) {        CarDto carDto = new CarDto();        carDto.setWheel(conversionService.convert(car.getWheel(), WheelDto.class);        return carDto;    }}
查看完整描述

2 回答

?
忽然笑

TA貢獻1806條經驗 獲得超5個贊

自從我提出這個問題以來已經一年多了,但現在我們已經在 MapStruct 項目本身中找到了答案 - MapStruct Spring Extensions項目。

項目中提供了一個示例作為示例CarMapper


查看完整回答
反對 回復 2023-08-23
?
森欄

TA貢獻1810條經驗 獲得超5個贊

您可以完全跳過傳遞 a WheelMapper,當您只有 a 時,CarMapper生成的也將包含映射<->CarMapperImpl的邏輯。無需將任何內容傳遞給,使您的問題過時。WheelWheelDtouses


carDto.setWheel( wheelToWheelDto( car.getWheel() ) );

用類似的方法;


protected WheelDto wheelToWheelDto(Wheel wheel) {

    if ( wheel == null ) {

        return null;

    }


    WheelDto wheelDto = new WheelDto();


    wheelDto.setName( wheel.getName() );


    return wheelDto;

}

我確實嘗試過實現ConversionServicethrough的智能注入MapStruct,但我認為這是不可能的。您需要來自的支持MapStruct才能實現這樣的壯舉。它甚至不考慮注入ConversionService。也許已經實現并使用的自定義通用映射器ConversionService可能會起作用,但我無法做到這一點!雖然我沒有看到任何原因,因為MapStruct已經從父映射器創建了所有必要的較小映射器......


查看完整回答
反對 回復 2023-08-23
?
冉冉說

TA貢獻1877條經驗 獲得超1個贊

坦率地說,我懷疑您是否可以ConversionService通過 . 實現自動連接到生成的映射器MapStruct。您在問題中描述的方式(通過注釋屬性連接各個映射器)可能是開箱即用的uses最佳方式。MapStruct


但是,如果您絕對需要使用某些 DTO 執行轉換ConversionService(例如,如果您有一些舊版轉換器,但您不想重構映射器),則可以使用解決方法。基本上,您可以使用靜態工廠的組合來獲取映射器接口中的Mappers.getMapper實例ConversionService和方法,以使用實例:defaultConversionService


@Mapper(componentModel = "spring")

public interface CarMapper extends Converter<Car, CarDto> {


    ConversionService CONVERSION_SERVICE = Mappers.getMapper(ConversionService.class);


    @Override

    default CarDto convert(Car car) {

        if (car == null) {

            return null;

        }


        CarDto carDto = new CarDto();


        carDto.setEngine(CONVERSION_SERVICE.convert(car.getEngine(), EngineDto.class));

        carDto.setWheel(CONVERSION_SERVICE.convert(car.getWheel(), WheelDto.class));


        return carDto;

    }

}

注意:如您所見,解決方法需要編寫CarMapper代碼。因此,在我看來,帶有注釋屬性的解決方案uses是更干凈的方法。例如,通過定義以下接口,您可以獲得幾乎相同的結果:


@Mapper(componentModel = "spring", 

        uses = {EngineMapper.class, WheelMapper.class}, 

        injectionStrategy = InjectionStrategy.CONSTRUCTOR)

public interface CarMapper extends Converter<Car, CarDto> {

    @Override

    CarDto convert(Car car);

生成的映射器:


@Component

public class CarMapperImpl implements CarMapper {


    private final EngineMapper engineMapper;

    private final WheelMapper wheelMapper;


    @Autowired

    public CarMapperImpl(EngineMapper engineMapper, WheelMapper wheelMapper) {


        this.engineMapper = engineMapper;

        this.wheelMapper = wheelMapper;

    }


    @Override

    public CarDto convert(Car car) {

        if (car == null) {

            return null;

        }


        CarDto carDto = new CarDto();


        carDto.setEngine(engineMapper.convert(car.getEngine()));

        carDto.setWheel(wheelMapper.convert(car.getWheel()));


        return carDto;

    }

}


查看完整回答
反對 回復 2023-08-23
  • 2 回答
  • 0 關注
  • 312 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號