Spring Boot 2.7.9:创建RestTemplate时出现Bean循环依赖异常
解决Spring Boot中RestTemplate创建的循环依赖问题
问题原因
你遇到的循环依赖是因为SrGroupController类同时承担了两个角色:既是Spring管理的Controller Bean,又是jiraRT这个RestTemplate Bean的定义者。Spring初始化Controller时需要注入jiraRT,但生成jiraRT的方法属于Controller类,Spring得先创建Controller实例才能调用该方法,最终形成循环链:SrGroupController → jiraRT RestTemplate → SrGroupController。
解决方案
方案1:将RestTemplate的Bean定义移到独立配置类(推荐)
把RestTemplate的配置抽离到专门的配置类中,让Controller只专注于处理请求:
@Configuration public class RestTemplateConfig { @Bean(name = "jiraRT") public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder.basicAuthentication("myuser", "password").build(); } }
修改后的Controller:
@RestController @RequestMapping("/api/srgrp/") public class SrGroupController { @Autowired @Qualifier("jiraRT") RestTemplate restTemplate; @RequestMapping(value = "ping", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public String ping() { return "ping works!"; } }
方案2:用构造方法注入+@Lazy延迟加载
如果不想移动Bean定义,可以通过延迟加载打破循环:
@RestController @RequestMapping("/api/srgrp/") public class SrGroupController { private final RestTemplate restTemplate; // 构造方法注入并添加@Lazy,延迟RestTemplate的初始化 public SrGroupController(@Qualifier("jiraRT") @Lazy RestTemplate restTemplate) { this.restTemplate = restTemplate; } @Bean(name = "jiraRT") public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder.basicAuthentication("myuser", "password").build(); } @RequestMapping(value = "ping", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public String ping() { return "ping works!"; } }
方案3:使用@DependsOn注解(备选,不推荐)
通过@DependsOn强制Spring先创建RestTemplate Bean,再初始化Controller:
@RestController @RequestMapping("/api/srgrp/") @DependsOn("jiraRT") // 强制优先创建jiraRT Bean public class SrGroupController { @Autowired @Qualifier("jiraRT") RestTemplate restTemplate; @Bean(name = "jiraRT") public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder.basicAuthentication("myuser", "password").build(); } @RequestMapping(value = "ping", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public String ping() { return "ping works!"; } }
内容的提问来源于stack exchange,提问作者Nidheesh
相关产品推荐
相关产品推荐

