Как создать или улучшить пользовательскую аннотацию, которая использует mapstruct - PullRequest
0 голосов
/ 07 февраля 2020

Mapsturct имеет аннотацию @Mapping с предопределенными атрибутами, например: @Mapping(source="", target="", qualifiedByName=""), что если я захочу добавить еще один атрибут и использовать его для вычисления логи c

, например: @Mapping(source="", target="", qualifiedByName="" , version="")

Я бы хотел передать ему номер версии, и в зависимости от версии он установил бы цель из источника.

Я пытался создать собственную аннотацию и использовать в ней @Mapping, но это не помогло

@CustomMapping(version = "1.0", mapping = @Mapping(source = "", target = "", qualifiedByName=""))

Ответы [ 2 ]

0 голосов
/ 08 февраля 2020

Основываясь на комментариях в вопросе, я понимаю немного больше, что нужно сделать. Основываясь на некоторых входных параметрах, необходимо создать различные методы отображения.

Не уверен, насколько сложна ваша логика c. Тем не менее, вы можете создать собственный процессор аннотаций, который мог бы создавать картографы MapStruct.

Давайте представим, что у вас есть

@CustomMapper
public interface MyMapper {
    @CustomMapping(version = "1.0", mappings = { 
        @Mapping(source = "numberOfSeats", target = "seatCount", qualifiedByName="")
    })
    @CustomMapping(version = "2.0", mappings = { 
        @Mapping(source = "numberOfSeats", target = "seats", qualifiedByName="")
    })
    CarDto map(Car car, String version);
}

Так что ваш процессор аннотаций должен будет обрабатывать CustomMapper.

Процессор также будет генерировать разные версионные интерфейсы MapStruct.

Итак:

@Mapper
public interface MyMapperV1 {

    @Mapping(source = "numberOfSeats", target = "seatCount", qualifiedByName="")
    CarDto map(Car car)
}

@Mapper
public interface MyMapperV2 {

    @Mapping(source = "numberOfSeats", target = "seats", qualifiedByName="")
    CarDto map(Car car)
}

И дополнительно реализация MyMapper. Это выглядит так:

public class MyMapperImpl {

    protected MyMapperV1 myMapperV1 = Mappers.getMapper(MyMapperV1.class):
    protected MyMapperV2 myMapperV2 = Mappers.getMapper(MyMapperV2.class):

    public CarDto map(Car car, String version) {
        if ("1.0".equals(version)) {
            return myMapperV1.map(car);
        } else {
            return myMapperV2.map(car);
        }
    }
}

По сути, цель состоит в том, чтобы ваш процессор генерировал интерфейсы, которые будут задействованы MapStruct в одном раунде компиляции. Это возможно при обработке аннотаций.

Другой вариант - написать мапперы MapStruct самостоятельно и в месте вызова выбрать тот, который подходит для версии. Это может быть проще на самом деле.

0 голосов
/ 07 февраля 2020

Почему бы вам просто не определить 2-ую отдельную аннотацию, которая будет использоваться вместе с @Mapping?

@Mapping(source="", target="", qualifiedByName="")
@MappingVersion("1.0")
CarDto carToCarDto(Car car);

Если вас беспокоит то, что вам нужно какое-то принуждение, эта версия всегда присутствует при использовании @Mapping, тогда вы можете просто написать процессор аннотаций , который делает это при компиляции -время.

...