Spring Bean循环依赖求助:Config与CurrencyConverterService互依赖
问题根源
你的循环依赖链是:Config类通过构造器注入了CurrencyConverterService,而CurrencyConverterService又依赖Config类中定义的RestTemplate Bean。Spring创建Config时需要先实例化CurrencyConverterService,但实例化CurrencyConverterService又需要RestTemplate,而RestTemplate是Config的内部Bean,还未完成创建,最终形成循环。
你之前尝试的@Lazy加错了位置,以及开启allow-circular-references没用,是因为循环的核心是Config和CurrencyConverterService的直接相互依赖,而非RestTemplate本身的延迟加载。
解决方案
方案1:移除Config类对CurrencyConverterService的直接依赖
不要在Config类的成员变量上注入CurrencyConverterService,而是在modelMapper Bean的创建方法中通过参数注入。这样Config本身不再依赖CurrencyConverterService,仅ModelMapper Bean依赖它,打破循环链。
修改后的Config类代码:
@Configuration public class Config { @Bean public RestTemplate restTemplate() { return new RestTemplate(); } // 直接在方法参数中注入CurrencyConverterService @Bean public ModelMapper modelMapper(CurrencyConverterService currencyConverter) { ModelMapper modelMapper = new ModelMapper(); // 这里正常使用currencyConverter做配置 ... return modelMapper; } }
方案2:将RestTemplate移到独立的配置类
把RestTemplate的Bean定义从Config类中拆分出来,放到单独的配置类里。这样CurrencyConverterService依赖的是独立配置类的RestTemplate,不再和Config类形成直接依赖。
示例代码:
// 新建RestTemplateConfig.java @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { return new RestTemplate(); } } // 原Config.java保持不变 @Configuration @RequiredArgsConstructor public class Config { private final CurrencyConverterService currencyConverter; @Bean public ModelMapper modelMapper() { ModelMapper modelMapper = new ModelMapper(); ... return modelMapper; } }
方案3:在Config类的CurrencyConverterService注入上添加@Lazy
如果不想调整类结构,可以给Config类中注入的CurrencyConverterService添加@Lazy注解,让Spring延迟实例化CurrencyConverterService,先完成Config和RestTemplate的创建,再处理CurrencyConverterService的依赖。
使用Lombok的写法:
@Configuration @RequiredArgsConstructor public class Config { // 给注入的服务加@Lazy @Lazy private final CurrencyConverterService currencyConverter; @Bean public RestTemplate restTemplate() { return new RestTemplate(); } @Bean public ModelMapper modelMapper() { ModelMapper modelMapper = new ModelMapper(); ... return modelMapper; } }
手动构造器注入的写法:
@Configuration public class Config { private final CurrencyConverterService currencyConverter; // 构造器参数上加@Lazy public Config(@Lazy CurrencyConverterService currencyConverter) { this.currencyConverter = currencyConverter; } // 后续Bean定义不变 }
内容的提问来源于stack exchange,提问作者Lulex97

