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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:22:35