You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring中CustomerMapper无法自动装配:找不到对应Bean的问题求助

MapStruct Mapper自动装配失败问题解决

问题描述

在Spring项目中,我通过MapStruct定义了CustomerMapper接口,并设置componentModel="spring",但在CustomerServiceIMPL实现类中用@Autowired注入该Mapper时,报错提示:Could not autowire. No beans of 'CustomerMapper' type found。想确认是否可以自动装配该Mapper,以及如何解决这个问题。

相关代码

CustomerMapper接口

import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface CustomerMapper {
    ResponseCustomerFilterDTO entityToResponseDTO(Customer customer);
}  

CustomerService接口

package com.class3.poinofsaleclass3.service;

import java.util.List;

public interface CustomerService {
    String addCustomer(CustomerSaveRequestDTO customerSaveRequestDTO);
    String updateCustomer(CustomerUpdateRequestDTO customerUpdateRequestDTO);
    CustomerDto getCustomerById(int id);
    List<CustomerDto> getAllCustomers();
    CustomerDto getCustomerByNic(String nic);
    ResponseCustomerFilterDTO getCustomerByIdFilter(int id);
}   

ResponseCustomerFilterDTO类

package com.class3.poinofsaleclass3.dto.responce;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class ResponseCustomerFilterDTO {
    private int customerId;
    private String customerAddress;
    private double customerSalary;
}   

CustomerServiceIMPL实现类

package com.class3.poinofsaleclass3.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class CustomerServiceIMPL implements CustomerService {

    @Autowired
    private CustomerRepo customerRepo;

    @Autowired
    private ModelMapper modelMapper;

    @Autowired
    private CustomerMapper customerMapper;  

    @Override
    public String addCustomer(CustomerSaveRequestDTO customerSaveRequestDTO) {
        Customer customer = new Customer(
                customerSaveRequestDTO.getCustomerName(),
                customerSaveRequestDTO.getCustomerAddress(),
                customerSaveRequestDTO.getCustomerSalary(),
                customerSaveRequestDTO.getContactNumber(),
                customerSaveRequestDTO.getNic(),
                false
        );
        if (!customerRepo.existsById(customer.getCustomerId())) {
            customerRepo.save(customer);
            return customer.getCustomerName() + "saved";
        } else {
            System.out.println("customer id already exsit");
            return "customer id already exsit";
        }
    }

    @Override
    public String updateCustomer(CustomerUpdateRequestDTO customerUpdateRequestDTO) {
        if (customerRepo.existsById(customerUpdateRequestDTO.getCustomerId())) {
            Customer customer = customerRepo.getById(customerUpdateRequestDTO.getCustomerId());
            customer.setCustomerName(customerUpdateRequestDTO.getCustomerName());
            customer.setCustomerAddress(customerUpdateRequestDTO.getCustomerAddress());
            customer.setCustomerSalary(customerUpdateRequestDTO.getCustomerSalary());
            customer.setContactNumber(customerUpdateRequestDTO.getContactNumber());
            customer.setNic(customerUpdateRequestDTO.getNic());
            customer.setActivestate(customerUpdateRequestDTO.isActivestate());
            return customerRepo.save(customer).getCustomerName() + "Updated";
        } else {
            System.out.println("this customer not at database");
            return "this customer not at database";
        }
    }

    @Override
    public CustomerDto getCustomerById(int id) {
        Optional<Customer> customer = customerRepo.findById(id);
        if (customer.isPresent()) {
            CustomerDto customerDto = modelMapper.map(customer.get(), CustomerDto.class);
            return customerDto;
        } else {
            return null;
        }
    }

    @Override
    public List<CustomerDto> getAllCustomers() {
        List<Customer> getCustomers = customerRepo.findAll();
        List<CustomerDto> customerDtos = modelMapper.map(getCustomers, new TypeToken<List<CustomerDto>>() {}.getType());
        return customerDtos;
    }

    @Override
    public CustomerDto getCustomerByNic(String nic) {
        Optional<Customer> customer = customerRepo.findByNicEquals(nic);
        if (customer.isPresent()) {
            CustomerDto customerDto = modelMapper.map(customer.get(), CustomerDto.class);
            return customerDto;
        } else {
            throw new NotFoundException("not found");
        }
    }

    @Override
    public ResponseCustomerFilterDTO getCustomerByIdFilter(int id) {
        Optional<Customer> customer = customerRepo.findById(id);
        if (customer.isPresent()) {
            ResponseCustomerFilterDTO responseCustomerFilterDTO = customerMapper.entityToResponseDTO(customer.get());
            return responseCustomerFilterDTO;
        } else {
            throw new NotFoundException("Not Found");
        }
    }
}  

问题分析与解决方法

结论:完全可以自动装配,只要配置正确,MapStruct会生成Spring管理的Bean实例。报错原因是Mapper的实现类未生成或Spring未扫描到,按以下步骤排查解决:

1. 检查MapStruct依赖是否完整

MapStruct需要核心依赖和注解处理器依赖,二者缺一不可,注解处理器负责编译时生成Mapper实现类。

Maven示例配置(pom.xml)

<dependencies>
    <!-- MapStruct核心依赖 -->
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>1.5.5.Final</version> <!-- 建议使用最新稳定版 -->
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>17</source> <!-- 匹配你的项目JDK版本 -->
                <target>17</target>
                <annotationProcessorPaths>
                    <!-- MapStruct注解处理器 -->
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>1.5.5.Final</version>
                    </path>
                    <!-- 如果项目用了Lombok,必须添加Lombok注解处理器,否则会和MapStruct冲突 -->
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>1.18.28</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

2. 启用IDE的注解处理器功能

  • IntelliJ IDEA:打开File > Settings > Build, Execution, Deployment > Compiler > Annotation Processors,勾选Enable annotation processing,确保MapStruct能在IDE编译时生成实现类。
  • Eclipse:需要安装MapStruct插件,并在项目设置中启用注解处理器。

3. 重新编译项目

MapStruct的Mapper实现类是编译时生成的,未编译的话Spring容器中不会有对应的Bean。执行以下操作:

  • Maven:运行mvn clean compile
  • Gradle:运行gradle clean build
  • 编译完成后,检查项目的target/generated-sources/annotations目录下是否生成了CustomerMapperImpl类,这是Spring要管理的Bean。

4. 确认Spring包扫描范围

如果CustomerMapper所在的包不在Spring默认扫描范围内(主启动类所在包及其子包),需要在主启动类上添加@ComponentScan指定扫描路径:

@SpringBootApplication
@ComponentScan(basePackages = {"com.class3.poinofsaleclass3", "你的Mapper所在包路径"})
public class PointOfSaleClass3Application {
    public static void main(String[] args) {
        SpringApplication.run(PointOfSaleClass3Application.class, args);
    }
}

5. 改用构造器注入(推荐)

尽量避免字段注入,改用构造器注入,这是Spring官方推荐的方式,能避免注入时机问题,同时提高代码可测试性:

@Service
public class CustomerServiceIMPL implements CustomerService {

    private final CustomerRepo customerRepo;
    private final ModelMapper modelMapper;
    private final CustomerMapper customerMapper;

    // 构造器注入,无需@Autowired(Spring 4.3+自动支持)
    public CustomerServiceIMPL(CustomerRepo customerRepo, ModelMapper modelMapper, CustomerMapper customerMapper) {
        this.customerRepo = customerRepo;
        this.modelMapper = modelMapper;
        this.customerMapper = customerMapper;
    }

    // 其他业务方法...
}

内容的提问来源于stack exchange,提问作者Thushan kavinda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 12:39:51