【问题标题】:Mapstruct 1.2.0 not generating mapper class in springboot 2.0.0.M3 + lombokMapstruct 1.2.0 未在 springboot 2.0.0.M3 + lombok 中生成映射器类
【发布时间】:2018-02-12 04:25:03
【问题描述】:

我正在尝试组合一个结合以下技术的示例项目:

  • 弹簧靴(2.0.0.M3)
  • Mapstruct (1.2.0.CR1)
  • 龙目岛 (1.16.18)

我已经定义了这个映射器:

@Mapper(componentModel = "spring")
public interface SourceToTargetMapper {

    SourceToTargetMapper MAPPER = Mappers.getMapper( SourceToTargetMapper.class );

    @Mappings({ 
        @Mapping(source = "characteristics", target = "description"),
        @Mapping(source = "identifier", target = "id") 
    })
    public Target toTarget(Source source);
}

我遇到的问题是没有生成实现 SourceToTargetMapper 接口的类。

这是我运行单元测试时得到的跟踪:

2017-09-04 00:13:24.726 ERROR 1712 --- [           main] o.s.test.context.TestContextManager      : Caught exception while allowing TestExecutionListener [org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@568bf312] to prepare test instance [io.alfredux.demo.MapperTest@5ccbeb64]

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'io.alfredux.demo.MapperTest': Unsatisfied dependency expressed through field 'sourceToTargetMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.alfredux.demo.mapper.SourceToTargetMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:570) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:356) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:399) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118) ~[spring-test-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) ~[spring-test-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:44) ~[spring-boot-test-autoconfigure-2.0.0.M3.jar:2.0.0.M3]
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:242) ~[spring-test-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227) [spring-test-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289) [spring-test-5.0.0.RC3.jar:5.0.0.RC3]
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291) [spring-test-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246) [spring-test-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) [spring-test-5.0.0.RC3.jar:5.0.0.RC3]
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) [spring-test-5.0.0.RC3.jar:5.0.0.RC3]
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) [spring-test-5.0.0.RC3.jar:5.0.0.RC3]
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) [.cp/:na]
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.alfredux.demo.mapper.SourceToTargetMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1486) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1097) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1058) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:567) ~[spring-beans-5.0.0.RC3.jar:5.0.0.RC3]
    ... 29 common frames omitted

我相信我的 pom.xml 的 build/plugin 部分中缺少或放错了地方 文件

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${org.mapstruct.version}</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

项目的源代码可以在这里查看:

https://github.com/Alfredux79/mapstruct-lombock-springboot/tree/stack-overflow-question

问题可以通过下载分支并运行命令重现:

mvn test

谢谢!

【问题讨论】:

    标签: spring maven spring-boot lombok mapstruct


    【解决方案1】:

    您没有正确配置编译器。运行mvn clean compile后,你应该会在target/generated-sources下看到一些MapStruct生成的文件。

    您缺少 maven-compiler-plugin 配置:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.6.2</version>
        <configuration>
            <source>1.7</source>
            <target>1.7</target>
            <annotationProcessorPaths>
                <path>
                    <groupId>org.mapstruct</groupId>
                    <artifactId>mapstruct-processor</artifactId>
                    <version>${org.mapstruct.version}</version>
                </path>
            </annotationProcessorPaths>
        </configuration>
    </plugin>
    

    this example

    【讨论】:

    • 如果我使用 3.1 版本,项目编译但不生成映射器类如果我使用高于 3.5 的版本 maven 无法检测到 lombok 生成的方法
    • 它与 3.5 而不是 3.1 一起工作的原因是因为 annotationProcessorPaths 是从 3.5 开始支持的。如果设置了annotationProcessorPaths,那么 Maven 编译器只使用在那里定义的处理器。因此 Lombok 处理器没有被调用,这导致它没有启用 MapStruct 使用的标志,以便知道类型是否完整并准备好进行处理
    【解决方案2】:

    这是我的 pom.xml 构建部分的最终版本的样子:

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>
    

    随着这种变化,类正在生成。

    解决方案是提供的答案和为 lombock 添加注释处理器的混合。

    【讨论】:

    【解决方案3】:

    尝试添加此依赖项

    <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-lang3</artifactId>
         <version>3.3.2</version>
         <type>jar</type>
    </dependency>
    

    【讨论】:

      【解决方案4】:

      pom.xml 中添加以下更改,以确保在 maven 中使用最新的 m2e-apt 插件。

      <properties>
        <!-- automatically run annotation processors within the incremental compilation -->
        <m2e.apt.activation>jdt_apt</m2e.apt.activation>
      </properties>
      

      对于 eclipse 或 spring 套件 IDE 支持,请安装官方 mapstruct 插件。

      https://marketplace.eclipse.org/content/mapstruct-eclipse-plugin#group-external-install-button

      【讨论】:

        【解决方案5】:

        我在使用 spring boot 时遇到了同样的问题。

        问题是,在 maven 注释处理器路径插件上,我已经为 MapStruct 路径指定了注释配置,但 maven 仍然会给出 unstaisfied 依赖错误。正在生成 mapstruct 映射器的实现。我生成的注释文件夹也存在于类路径中。还是没用。

        解决办法?这是由龙目岛项目引起的。我没有在我的代码中使用项目 lombok,但它仍然最终出现在我的依赖关系树上。我也在lombok的pom.xml文件中指定了注解配置路径,最后,这该死的东西打包好了。

        *this* 差点把自己送进精神病院。

        【讨论】:

          猜你喜欢
          • 2019-12-03
          • 1970-01-01
          • 2020-08-02
          • 1970-01-01
          • 2020-03-19
          • 2018-01-13
          • 2016-07-14
          • 2017-11-09
          • 1970-01-01
          相关资源
          最近更新 更多