| 知乎专栏 |
添加依赖
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>2.0.12</version>
</dependency>
package cn.aigcsst;
import cn.aigcsst.websocket.WebsocketEndpoint;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableJpaRepositories
@EnableAutoConfiguration
@EnableCaching
@EnableAsync
@EnableRetry
public class Application {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
@Value("${spring.application.name}")
public String name;
static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);
WebsocketEndpoint.setApplicationContext(applicationContext);
}
@PostConstruct
public void init() {
logger.info(String.format("==================== %s 系统启动 ====================", name));
}
@PreDestroy
public void destroy() {
logger.info(String.format("==================== %s 系统销毁 ====================", name));
}
}
package cn.aigcsst.controller.debug;
import cn.aigcsst.annotation.TokenPass;
import cn.aigcsst.service.AiService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Retryable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
@TokenPass
@RequestMapping("/test")
public class TestController {
@GetMapping
@Retryable(RuntimeException.class)
public void index() {
log.warn("Test");
throw new RuntimeException();
}
}
输出日志
api | 2026-01-12 17:52:53.288 WARN --- [tomcat-handler-0] c.a.controller.debug.TestController : Test <- index:23 api | 2026-01-12 17:52:53.303 WARN --- [tomcat-handler-0] cn.aigcsst.service.AiService : ---> Test ---> <- agent:42 api | 2026-01-12 17:52:54.305 WARN --- [tomcat-handler-0] cn.aigcsst.service.AiService : ---> Test ---> <- agent:42 api | 2026-01-12 17:52:55.306 WARN --- [tomcat-handler-0] cn.aigcsst.service.AiService : ---> Test ---> <- agent:42 api | 2026-01-12 17:52:55.308 ERROR --- [tomcat-handler-0] c.aigcsst.config.GloablControllerAdvice : RuntimeException: null <- handleException:19
@Retryable(value = RuntimeException.class, maxAttempts = 2, backoff = @Backoff(delay = 1000, multiplier = 2))
public void service() {
Random random = new Random();
int i = random.nextInt();
if (i == 0) {
System.out.println("i = " + i + " " + LocalDateTime.now());
throw new RuntimeException("service failed!");
}
}