【问题标题】:MapStruct implementation is not working in Spring Boot Web ApplicationMapStruct 实现在 Spring Boot Web 应用程序中不起作用
【发布时间】:2017-11-11 11:44:22
【问题描述】:

我是 Spring Boot 和 MapStruct 工具的新手。

早些时候,一个项目(由其他团队使用这些技术编写)没有启动。然后,我在 Mapper Abstract Class 中进行了一些更改,但现在映射器对象在应用程序启动时变为 null。

映射器抽象类:

@Mapper(componentModel = "spring")
public abstract class UserAndEmployeeMapper {

    public UserAndEmployeeMapper INSTANCE = Mappers.getMapper( UserAndEmployeeMapper.class );

    @Mapping(source = "username", target = "name")
    @Mapping(source = "ssn", target = "ssn", defaultValue = "xxxxxx" )
    @Mapping(target = "salary", constant = "34.67")
    @Mapping(target = "dob", dateFormat = "dd/MM/yyyy", constant = "10/12/2002")
    public abstract Employee mapToEmployee(User user);

    public abstract List<Employee> mapToEmployee(List<User> users);

    @Mapping(source = "name", target = "username")
    public abstract User mapToUser(Employee employee);

    public abstract List<User> mapToUser(List<Employee> employees);

}

LoginServiceImpl 类

@Service("loginService")
public class LoginServiceImpl implements LoginService{

    private static final AtomicLong counter = new AtomicLong();

    @Autowired
    private EmployeeDao employeeDao;

    private UserAndEmployeeMapper userAndEmployeeMapper;
...

}

pom.xml

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

在 LoginServiceImpl 中添加 @Autowired 后,应用程序未启动并显示以下错误日志

***************************
APPLICATION FAILED TO START
***************************

Description:

Field userAndEmployeeMapper in org.service.impl.LoginServiceImpl required a bean of type 'org.mapper.UserAndEmployeeMapper' that could not be found.


Action:

Consider defining a bean of type 'org.mapper.UserAndEmployeeMapper' in your configuration.

有什么建议吗?

【问题讨论】:

  • 您是否尝试过与您所说的 spring boot 错误完全相同的操作?我的意思是定义 UserAndEmployeeMapper spring bean。看来 Mapper 注释不能用作 bean 定义
  • @Normal:在 UserAndEmployeeMapper 抽象类之上声明组件会给出相同的错误输出。
  • 没注意到它是抽象的,抱歉。这似乎是非常相似的问题stackoverflow.com/questions/32609755/…
  • 如何调用应用程序?通过 maven / gradle 还是通过 IDE?你的Application 班级在哪里?

标签: java spring-boot entity dto mapstruct


【解决方案1】:

首先,public UserAndEmployeeMapper INSTANCE = Mappers.getMapper( UserAndEmployeeMapper.class ); 只能与默认组件模型一起使用,否则您将面临UserAndEmployeeMapper 未正确初始化的风险。

你的LoginServiceImpl中的UserAndEmployeeMapper必须用@Autowired注解,否则Spring不能注入,这就是null的原因。

我不知道你的包结构。如果您的 Spring Boot 应用程序类在包 org 中,那么它将选择 UserAndEmployeeMapperImpl。否则请确保 spring 配置选择UserAndEmployeeMapperImpl

如果上述所有内容均已正确设置,并且您正在通过 IDE 启动应用程序,请确保 target/generated-sources 或 Gradle 的替代品是您的源代码的一部分并被选中。查看IDE Support 以确保您已为 IDE 正确设置注释处理器发现。例如,IntelliJ 不会使用您当前的设置调用 MapStruct 注释处理器,它不会从 maven 编译器中获取 annotationProcessorPaths

【讨论】:

  • 你在说这个组件模型@Mapper(componentModel = "spring") 吗?
  • 是的,我说的是那个
  • 我已将 Mapper 类更改为接口 public interface UserAndEmployeeMapper。现在 UserAndEmployeerMapper 对象在 LoginServiceImpl 类中被初始化。
  • 为什么 Spring 不能将 bean 作为抽象类注入真的很奇怪。它应该起作用了。很高兴你已经解决了你的问题。关于spring,其实还是推荐使用接口而不是抽象类
【解决方案2】:

将抽象类作为接口对我有用。

public interface UserAndEmployeeMapper {

【讨论】:

  • 对于找不到映射器失败位置的任何人,设置 unmappedTargetPolicy 也很有用(例如 @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.WARN)
【解决方案3】:

springfox-swagger2 依赖项在排除它并在 pom.xml 中添加特定版本的 mapstruct 依赖项后加载旧版本的 mapstruct,它开始生成源

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
<exclusions>
 <exclusion>
 <groupId>org.mapstruct</groupId>
  <artifactId>mapstruct</artifactId>
 </exclusion>
</exclusions>

在map struct下面添加了依赖

<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.0.Beta1</version>

【讨论】:

    【解决方案4】:

    为了使所有映射器类都符合 Spring bean 的要求,请将以下 compilerArgs 添加到您的 maven-compiler-plugin。

    <compilerArgs>
    <arg>-Amapstruct.suppressGeneratorTimestamp=true</arg>
    <arg>-Amapstruct.defaultComponentModel=spring</arg>
    </compilerArgs> 
    

    如果使用 maven-processor-plugin 添加以下选项

    <options>                       
    <mapstruct.suppressGeneratorTimestamp>
    true
    </mapstruct.suppressGeneratorTimestamp>                      
    <mapstruct.defaultComponentModel>
    spring
    </mapstruct.defaultComponentModel>
    </options>
    

    【讨论】:

      【解决方案5】:

      就我而言,我认为错误是由于 build.gradle 不完整造成的。

      之前

      dependencies {
          compile group: 'org.mapstruct', name: 'mapstruct-processor', version: '1.2.0.Final'
      }
      

      之后

      apply plugin: 'net.ltgt.apt'
      
      dependencies {
          compile group: 'org.mapstruct', name: 'mapstruct-processor', version: '1.2.0.Final'
          compile group: 'org.mapstruct', name: 'mapstruct-jdk8', version: '1.2.0.Final'
          apt 'org.mapstruct:mapstruct-processor:1.2.0.Final'
      }
      
      
      buildscript {
          repositories {
              mavenCentral()
              maven {
                  url "https://plugins.gradle.org/m2/"
              }
          }
          dependencies {
              classpath("net.ltgt.gradle:gradle-apt-plugin:0.9")
          }
      }
      

      确保您已正确配置 build.gradle,如the docs.中所述

      【讨论】:

        【解决方案6】:

        如果使用 Eclipse,您可能需要安装 m2e-apt 插件。

        它将在 IDE 中为 MapStruct 启用注释处理器。

        【讨论】:

        • 如果使用 intelliJ 会怎样?
        猜你喜欢
        • 2020-08-08
        • 2018-02-22
        • 1970-01-01
        • 2018-03-15
        • 2021-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多