Autowired注入AlertsService返回null,如何获取appointmentAlertDays?
问题根源
问题出在**AppointmentAlertProvider是通过new AppointmentAlertProvider()手动创建的实例**,这类实例不在Spring容器的管理范围内,Spring不会自动为其注入@Autowired标记的字段,所以alertsService会返回null。而appointmentRepository看起来正常,大概率是你在测试中手动mock并赋值给了这个实例,但没对AlertsService做同样处理。
解决方案
要让Spring自动注入AlertsService,必须让AppointmentAlertProvider成为Spring容器管理的Bean,以下是几种可行方案:
方案1:修改工厂类,从Spring容器获取Bean
调整AlertProviderFactory,注入ApplicationContext,通过容器获取Bean而非手动new:
@Component public class AlertProviderFactory { private final ApplicationContext applicationContext; // 构造注入ApplicationContext public AlertProviderFactory(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } public AlertProvider getAlertProvider(String alertType) { if (alertType == null || alertType.isEmpty()) return null; if ("appointment-alert".equals(alertType)) { // 从Spring容器获取管理的Bean实例 return applicationContext.getBean(AppointmentAlertProvider.class); } throw new IllegalArgumentException("Unknown alertType " + alertType); } }
方案2(不推荐但兼容静态方法):静态持有ApplicationContext
如果必须保留静态工厂方法,可以通过构造注入把ApplicationContext赋值给静态变量:
@Component public class AlertProviderFactory { private static ApplicationContext applicationContext; // 构造注入并赋值给静态变量 public AlertProviderFactory(ApplicationContext ctx) { applicationContext = ctx; } public static AlertProvider getAlertProvider(String alertType) { if (alertType == null || alertType.isEmpty()) return null; if ("appointment-alert".equals(alertType)) { return applicationContext.getBean(AppointmentAlertProvider.class); } throw new IllegalArgumentException("Unknown alertType " + alertType); } }
测试类调整
确保测试中使用Spring管理的AlertProviderFactory实例,这样获取的AppointmentAlertProvider才会被自动注入依赖:
@SpringBootTest class AppointmentAlertProviderTest { @Autowired private AlertProviderFactory alertProviderFactory; @MockBean private AppointmentRepository appointmentRepository; @Autowired private AppointmentMapper appointmentMapper; @Test void findLatest() { Appointment appointmentRequest = generateDummyAppointment(); Vehicle vehicle = generateDummyVehicle(); AppointmentEntity appointmentEntity = appointmentMapper.map(appointmentRequest, vehicle, null); when(appointmentRepository.findAllByCustomerId(anyString())).thenReturn(List.of(appointmentEntity)); AlertProvider provider = alertProviderFactory.getAlertProvider("appointment-alert"); List<AppointmentEntity> appointmentEntities = provider.findLatest("customerId"); assertThat(appointmentEntities.size()).isOne(); } }
内容的提问来源于stack exchange,提问作者clement mensah
相关产品推荐
相关产品推荐

