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

Spring Boot中@Component注入始终为null问题排查求助

Mapper类注入后始终为Null的问题排查

我定义了两个标注@Component的Mapper类:

ClientMapper代码

@Component
public class ClientMapper {
  public Client convert(ClientEntity clientEntity) {
    Client client = new Client();
    BeanUtils.copyProperties(clientEntity, client);
    return client;
  }

  public ClientEntity convert(Client client) {
    ClientEntity clientEntity = new ClientEntity();
    BeanUtils.copyProperties(client, clientEntity);
    return clientEntity;
  }
}

OrderMapper代码

@Component
public class OrderMapper {
  public Order convert(OrderEntity orderEntity) {
    Order order = new Order();
    BeanUtils.copyProperties(orderEntity, order);
    return order;
  }

  public OrderEntity convert(Order order) {
    OrderEntity orderEntity = new OrderEntity();
    BeanUtils.copyProperties(order, orderEntity);
    return orderEntity;
  }
}

我通过@AllArgsConstructor将它们注入到不同的Service实现类中:

ClientServiceImpl代码

@Service
@AllArgsConstructor
public class ClientServiceImpl implements ClientService {

  private final ClientMapper clientMapper;
  private final ClientRepository clientRepository;
}

OrderServiceImpl代码

@Service
@AllArgsConstructor
public class OrderServiceImpl implements OrderService {

  private final OrderMapper orderMapper;
  private final OrderRepository orderRepository;
  private final OrderNumberRepository orderNumberRepository;
}

但这些Mapper始终为null,我没有用new关键字创建实例。而且Repository接口注入正常,说明构造注入方式是有效的。(附代码截图:[显示Mapper为null的代码截图])

补充:测试类中对Service使用了@InjectMocks注解,会不会是这个导致的问题?

OrderServiceTest代码

@ExtendWith(MockitoExtension.class)
public class OrderServiceTest {
  @Mock
  private OrderRepository orderRepository;
  @InjectMocks
  private OrderServiceImpl orderService;
}

问题原因及解决方案

问题确实出在@InjectMocks注解上:

  • Mockito的@InjectMocks只会注入被@Mock或@Spy标记的对象,对于没有被Mock的Bean(比如你的Mapper类),它不会自动从Spring容器中获取实例,直接留空导致Mapper为null。

解决方法有三种:

  1. 给Mapper添加@Mock或@Spy注解:
    • 如果测试不需要Mapper的真实转换逻辑,给Mapper加@Mock即可;
    • 如果需要真实逻辑,用@Spy并手动实例化(或者结合Spring的@SpyBean注入)
    @ExtendWith(MockitoExtension.class)
    public class OrderServiceTest {
      @Mock
      private OrderRepository orderRepository;
      @Mock
      private OrderNumberRepository orderNumberRepository;
      @Spy
      private OrderMapper orderMapper = new OrderMapper();
      @InjectMocks
      private OrderServiceImpl orderService;
    }
    
  2. 改用Spring Boot完整测试框架:
    如果需要完整的Spring容器上下文,用@SpringBootTest代替MockitoExtension,配合@Autowired注入Service,所有Spring管理的Bean都会被正确注入,同时用@MockBean替换需要Mock的Repository:
    @SpringBootTest
    public class OrderServiceTest {
      @Autowired
      private OrderServiceImpl orderService;
      @MockBean
      private OrderRepository orderRepository;
      @MockBean
      private OrderNumberRepository orderNumberRepository;
    }
    
  3. 检查包扫描范围:
    额外确认Mapper类是否在Spring Boot的默认包扫描范围内(主启动类所在包的子包),如果不在,需要添加@ComponentScan指定扫描路径——不过Repository能正常注入的话,大概率包扫描没问题。

内容的提问来源于stack exchange,提问作者Oleksandr Ovcharenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 19:35:31