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。
解决方法有三种:
- 给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; } - 如果测试不需要Mapper的真实转换逻辑,给Mapper加
- 改用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; } - 检查包扫描范围:
额外确认Mapper类是否在Spring Boot的默认包扫描范围内(主启动类所在包的子包),如果不在,需要添加@ComponentScan指定扫描路径——不过Repository能正常注入的话,大概率包扫描没问题。
内容的提问来源于stack exchange,提问作者Oleksandr Ovcharenko
相关产品推荐
相关产品推荐

