Не удается внедрить интерфейс mapstruct во время запуска приложения Spring

#java #spring #spring-boot #mapstruct

#java #spring #spring-boot #mapstruct

Вопрос:

У меня есть следующий mapper (mapstruct версии 1.3.1.Final).

 @Mapper(componentModel = "spring", uses = {}, unmappedTargetPolicy = ReportingPolicy.WARN)
public interface AccountMapper {
    @Mapping(source = "registrationDto.email", target = "email")
    @Mapping(source = "passwordDto.hashPassword", target = "password")
    Account from(RegistrationDto registrationDto, PasswordDto passwordDto);
}
  

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

 Parameter 1 of constructor in com.xx.xx.Controller required a bean of type 'com.xxx.AccountMapper' that could not be found.

Consider defining a bean of type 'com.xxx.AccountMapper' in your configuration.
  

Я попробовал решение с помощью декоратора. Добавив аннотацию @DecoratedWith(AccountMapperDecorator.class) для интерфейса и создав следующий класс.

 @Component
public abstract class AccountMapperDecorator implements AccountMapper {

    @Autowired
    @Qualifier("delegate")
    private AccountMapper delegate;

    @Override
    public Account from(RegistrationDto registrationDto, PasswordDto passwordDto) {
        return delegate.from(registrationDto, passwordDto);
    }
}
  

И затем я получаю.

 No qualifying bean of type 'com.xxx.AccountMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value="delegate")}
  

В чем может быть проблема в этом случае?

Ответ №1:

Вы запускали mvn package ? При поиске класса AccountMapperImpl в вашей IDE вы можете его найти? Если нет, то это проблема. Если вы не можете его найти, Spring тоже не сможет.

Возможно, вы забыли настроить (или неправильно настроили) mapstruct-processor в вашем pom.xml ? Есть ли у вас что-то вроде:

 <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.5.1</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <annotationProcessorPaths>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>...</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>
  

там?

Комментарии:

1. В вашем контроллере вы автоматически подключаете интерфейс или реализацию? Я имею в виду, что вы автоматически подключаете AccountMapper или AccountMapperDecorator?

2. Я бы автоматически подключил интерфейс ( AccountMapper ), тот факт, что есть некоторые AccountMapperImpl или AccountMapperDecorator , является просто деталью реализации. Но в этом примере нет необходимости создавать декоратор вручную.

Ответ №2:

Это ситуация, которая случается время от времени,
если вы заметили, то, вероятно, AccountMapperImpl не генерируется в target/build папках, есть несколько способов исправить это:

  • Попробуйте очистить out/build каталоги
  • Выполнить mvn clean compile или gradle clean compileJava
  • Настройте IDE для запуска вашего кода с maven/gradle
    введите описание изображения здесь
  • Убедитесь, что Annotation Processing включено