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

Spock测试Spring-retry服务报错:RetrySynchronizationManager.getContext()返回null

Spock测试Spring-retry服务空指针异常的解决方法

问题说明

编写Spock测试验证Spring-retry服务时,因测试上下文未正确初始化触发空指针异常:

无法调用org.springframework.retry.RetryContext.getRetryCount(),因为org.springframework.retry.support.RetrySynchronizationManager.getContext()返回null

解决步骤

1. 确保测试类加载Spring上下文

测试类必须添加@SpringBootTest或@ContextConfiguration注解,保证Spring容器初始化,Spring-retry相关Bean(如RetryTemplate)被正确注入。

示例测试类:

@SpringBootTest
class RetryServiceSpec extends Specification {
    @Autowired
    private RetryService retryService

    def "验证重试逻辑"() {
        when:
        def result = retryService.executeWithRetry()

        then:
        result == "执行成功"
    }
}

2. 规范业务代码中重试上下文的获取

业务代码中必须在RetryTemplate的回调方法内调用RetryContext,不能直接在回调外调用RetrySynchronizationManager.getContext()。

正确的服务层代码示例:

@Service
public class RetryService {
    @Autowired
    private RetryTemplate retryTemplate;

    public String executeWithRetry() {
        return retryTemplate.execute(retryContext -> {
            // 仅在回调内获取重试上下文
            int currentRetryCount = retryContext.getRetryCount();
            if (currentRetryCount < 2) {
                throw new RuntimeException("模拟异常触发重试");
            }
            return "执行成功";
        });
    }
}

3. 显式配置重试规则(可选)

通过@EnableRetry和自定义RetryTemplate Bean,明确重试次数、退避策略等配置:

@Configuration
@EnableRetry
public class RetryConfig {
    @Bean
    public RetryTemplate retryTemplate() {
        RetryTemplate retryTemplate = new RetryTemplate();
        
        // 设置最大重试次数
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(3);
        retryTemplate.setRetryPolicy(retryPolicy);
        
        // 设置固定退避时间
        FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
        backOffPolicy.setBackOffPeriod(1000);
        retryTemplate.setBackOffPolicy(backOffPolicy);
        
        return retryTemplate;
    }
}

4. 避免直接实例化服务类

测试中必须使用Spring容器注入的服务Bean,不能直接new实例,否则Spring-retry的切面或RetryTemplate不会生效。

核心原因

空指针异常的本质是测试未初始化Spring-retry的执行环境,或业务代码在RetryTemplate的执行上下文之外调用了RetrySynchronizationManager.getContext(),此时上下文未被设置,返回null。

内容的提问来源于stack exchange,提问作者Nathan Hughes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 15:14:58