MapStruct - @Mapper 注释不创建 bean

问题描述 投票:0回答:16

我从此源下载了应用程序https://github.com/springframeworkguru/spring5-mvc-rest/tree/vendor-api 我对 MapStruct 有疑问。

@Mapper
public interface CategoryMapper {

CategoryMapper INSTANCE = Mappers.getMapper(CategoryMapper.class);


CategoryDTO categoryToCategoryDTO(Category category);

}

@Data
public class CategoryDTO {
    private Long id;
    private String name;
}

域类:

@Data
@Entity
public class Category {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}

服务等级:

@Service
public class CategoryServiceImpl implements CategoryService {

    private final CategoryMapper categoryMapper;
    private final CategoryRepository categoryRepository;

    public CategoryServiceImpl(CategoryMapper categoryMapper, CategoryRepository categoryRepository) {
        this.categoryMapper = categoryMapper;
        this.categoryRepository = categoryRepository;
    }
}

在 pom.xml 依赖项中,我只粘贴两个::

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <org.mapstruct.version>1.2.0.CR2</org.mapstruct.version>
</properties>
<dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-jdk8</artifactId>
        <version>${org.mapstruct.version}</version>
</dependency>

和插件:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.7.0</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <annotationProcessorPaths>
            <path>
                 <groupId>org.projectlombok</groupId>
                 <artifactId>lombok</artifactId>
                 <version>${lombok.version}</version>
            </path>
            <path>
                 <groupId>org.mapstruct</groupId>
                 <artifactId>mapstruct-processor</artifactId>
                 <version>${org.mapstruct.version}</version>
           </path>
        </annotationProcessorPaths>
        <compilerArgs>
           <compilerArg>
                 -Amapstruct.defaultComponentModel=spring
           </compilerArg>
        </compilerArgs>
    </configuration>
</plugin>

描述:

Parameter 0 of constructor in 
guru.springfamework.services.CategoryServiceImpl required a bean of type 'guru.springfamework.api.v1.mapper.CategoryMapper' that could not be found.

行动:

Consider defining a bean of type 'guru.springfamework.api.v1.mapper.CategoryMapper' in your configuration.

我认为在我的 Intellij 注释 @Mapper 中不要为映射器创建 bean。 我没有更改 John GitHub 上的代码。 有什么想法吗? 我尝试将路径生成的源更改为目标,但这没有帮助 感谢您的帮助。

spring mapper mapstruct
16个回答
45
投票

我通过这样做解决了错误

  1. mvn 全新安装
  2. 也将其添加到您的 pom 中

       <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.7.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>${lombok.version}</version>
                    </path>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${org.mapstruct.version}</version>
                    </path>
                </annotationProcessorPaths>
                <compilerArgs>
                    <compilerArg>
                           -Amapstruct.defaultComponentModel=spring
                    </compilerArg>
                </compilerArgs>
            </configuration>
        </plugin>
    

13
投票

问题是使用

@Mapper
构造将生成一个类 without 默认情况下使用@Component注解。

您可能没有使用 Maven 来编译您的项目。确保运行 Maven

clean
install
,或手动传入编译器参数
mapstruct.defaultComponentModel=spring

自从您使用:

    <compilerArgs>
       <compilerArg>
             -Amapstruct.defaultComponentModel=spring
       </compilerArg>
    </compilerArgs>

这将告诉

MapStruct
生成
Spring Component

如果你检查编译后的目标类,并在反编译器中打开它(如果你的 IDE 支持此功能),应该有一个用 @Component 注释的

CategoryMapperImpl


13
投票

为了将映射器用作bean并使用

@Autowired
,只需将映射器声明为
@Mapper(componentModel = "spring")
即可。然后将其注入到需要的地方即可。


8
投票

在您的 Mapper 类中,使用

@Mapper(componentModel = "spring")
而不是仅
@Mapper

run mvn clean install
,就是这样!你完成了!

以及它的替代方案,是在pom.xml插件中定义编译器参数,如下所示!

 <plugin>
     <configuration>
         <compilerArgs>
             <compilerArg>
                 -Amapstruct.defaultComponentModel=spring
             </compilerArg>
         </compilerArgs>
     </configuration>
 </plugin>

7
投票
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>1.4.2.Final</version>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>1.4.2.Final</version>
    </dependency>

添加这两个依赖项解决了我的问题,创建bean所需的处理器(https://mvnrepository.com/artifact/org.mapstruct/mapstruct-processor),如果构造函数上的红线打扰你(它不打扰编译器)

@Autowired(required = false)
添加这个。


6
投票

我也有同样的问题。在 Gradle 中,我通过添加新的依赖项解决了这个问题:

compileOnly('org.mapstruct:mapstruct-processor:1.3.0.Beta2')

所有必要的依赖项应如下所示:

compile('org.mapstruct:mapstruct:1.3.0.Beta2')
compileOnly('org.mapstruct:mapstruct-processor:1.3.0.Beta2')
annotationProcessor('org.mapstruct:mapstruct-processor:1.3.0.Beta2')

3
投票

当我为两个依赖项添加注释处理器时,它对我有用。

annotationProcessor group: 'org.mapstruct', name: 'mapstruct', version: '1.4.2.Final'
implementation group: 'org.mapstruct', name: 'mapstruct', version: '1.4.2.Final'
annotationProcessor group: 'org.mapstruct', name: 'mapstruct-processor', version: '1.4.2.Final'
implementation group: 'org.mapstruct', name: 'mapstruct-processor', version: '1.4.2.Final'

另外,请确保使用

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

2
投票

我认为这仅在 IntelliJ 中不起作用。有一个已知问题,IntelliJ 实际上不会从 Maven 编译器获取注释处理器

annotationProcessorPaths
(有关更多信息,请参阅 IDEA-150621)。

最重要的是,链接存储库中的示例违反了 MapStruct 最佳实践。当使用

spring
componentModel
时,切勿使用
Mappers.getMapper
。原因是工厂将无法正确构建映射器,因为它应该通过 spring 构建。此外,编译器参数
mapstruct.defaultComponentModel
可能会破坏与 IDE 的集成,因为它没有被拾取(您还需要在 IntelliJ 设置中设置它)


2
投票

这对我有用:

  1. POM 依赖关系:

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <scope>provided</scope>
</dependency>

  1. POM 插件:
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.7.0</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <annotationProcessorPaths>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>${org.mapstruct.version}</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>
  1. componentModel = "spring"
    注释中具有
    @MapStruct
    参数。
  2. 在您的项目上运行
    mvn clean

我不认为你真的需要在 POM 中声明以下编译器参数,因为``componentModel = "spring"` 应该足够了。

<plugin>
     <configuration>
         <compilerArgs>
             <compilerArg>
                 -Amapstruct.defaultComponentModel=spring
             </compilerArg>
         </compilerArgs>
     </configuration>
</plugin>

我从JHipster生成的微服务应用程序项目中获取了这些代码片段。


2
投票

我通过首先在环境变量中安装 MAVEN_HOME 然后执行 mvn clean install 解决了这个问题。我发现我在 eclipse 中运行我的项目,然后在 Intellij 中运行,而没有安装 maven。


1
投票

对我来说,这是接口/抽象类上的

componentModel
注释中缺少
@Mapper
。 所以这不起作用:

@Mapper

但这有效:

@Mapper(componentModel = "spring")


1
投票

在映射器类上使用此注释,并且不要添加插件,因为此注释将创建一个 bean。

@Mapper(componentModel = "spring")

0
投票

您必须在 IntelliJ 中启用注释处理器,

设置 -> 构建、执行、部署 -> 编译器 -> 注解 处理器并单击启用注释处理复选框。


0
投票

你首先必须像这样使用Mapper

To use mappers as beans and use **@Autowired**,
just declare mappers as @Mapper(componentModel = "spring"). 
Then just inject it wherever you need this.

此外,每次创建新的映射器类时,请始终记住执行mvn clean install

它会在目标文件夹中创建你的mapper接口的实现文件,然后你就可以运行你的Spring项目了。


0
投票

@ComponentScan(“guru.springfamework.api.v1.mapper”)

将其添加到配置类或 MainClass 下


0
投票

请添加您的映射器类。

@Mapper(componentModel = "spring")

所以,代替

@Mapper
添加
@Mapper(componentModel = "spring")

© www.soinside.com 2019 - 2024. All rights reserved.