Могу ли я автоматически подключить компонент к интерфейсу? - PullRequest
0 голосов
/ 14 мая 2018

Я использую MapStruct, и для этого мне нужно определить интерфейс с соответствующей функцией отображения.Можно реализовать некоторую логику, используя метод default, аннотированный @BeforeMapping и @ AfterMapping .В таком аннотированном методе по умолчанию я хочу использовать класс конфигурации моего приложения SpringBoot.Как я могу это сделать?Можно ли автоматически связать такую ​​конфигурацию (бин) с интерфейсом?Как должен выглядеть такой код?


Из документации и подсказки я узнал, что вместо интерфейса могу использовать переменную @Context или абстрактный класс.

Я попробовал оба тогда.Используя абстрактный класс, он работал хорошо, как требовалось, но с помощью переменной @Context метод по умолчанию не вызывался.

Вот основной метод отображения:

@Mapping(target = "myTarget.partNumber", ignore = true)
public MyTarget mapSource2Target(final MySource mySource, final PartNumberMapConfiguration partNumberMapConfiguration);

и afterMapping method:

@AfterMapping
default void afterMapping(final @MappingTarget MyTarget target, final MySource source, final @Context PartNumberMapConfiguration partNumberMapConfiguration) {. . . }

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

Вот класс, который я намерен использовать как с @Context:

@Component("PartNumberMap")
@PropertySource("classpath:abc.properties")
@ConfigurationProperties(prefix = "abc")
public class PartNumberMapConfiguration {

    private Map<String, String> partNumberMap = new HashMap<String, String>();

    public Map<String, String> getPartNumberMap() {
        return partNumberMap;
    }

    public void setPartNumberMap(final Map<String, String> partNumberMap) {
        this.partNumberMap = partNumberMap;
    }
}

1 Ответ

0 голосов
/ 14 мая 2018

Вы не можете автоматически связать компонент в интерфейс.Однако вы можете использовать @Context из MapStruct 1.2.0.

Например:

@Mapper
public interface MyMapper {


    Target map(Source source, @Context MyCustomService service);

    @AfterMapper
    void after(Source source, @MappingTarget Target target, @Context MyCustomService service) {
        // Do what you need here
    }
}

Другой вариант - использовать абстрактный интерфейс вместо интерфейса.

@Mapper
public abstract class MyMapper {

    private MyCustomService service;


    public abstract Target map(Source source);


    @AfterMapping
    protected after(Source source, @MappingTarget Target target) {
        // Use the service here
    }

    @Autowired
    public void setService(MyCustomService service) {
        this.service = service.
    }    
}
...