経緯
SpringBoot2.6→3.0にバージョンアップした際に、依存関係が循環しているみたいなメッセージがでてきた。具体的な内容は、下記の通り
The dependencies of some of the beans in the application context form a cycle: minhonController (field private com.galewings.service.MinhonService com.galewings.controller.MinhonController.service) ┌─────┐ | minhonService (field okhttp3.OkHttpClient com.galewings.service.MinhonService.okHttpClient) └─────┘
発生していた例外(一部抜粋)
2023/07/05 08:59:07 DEBUG [restartedMain] - Application failed to start due to an exception org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'minhonService': Requested bean is currently in creation: Is there an unresolvable circular reference? at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:355) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:227) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:412) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1324) //・・・・
実装内容
原因となる実装
原因となっていた箇所のソース
@Service @Component public class MinhonService { // ・・・・ @Autowired OkHttpClient client; @Autowired private RestTemplate restTemplate; @Bean public OkHttpClient okHttpClient() { return new OkHttpClient(); } @Bean public RestTemplate restTemplate() { return new RestTemplate(); } // ・・・・ }
おそらく、okHttpClientのインスタンスがほしいけど、MinhonServiceのインスタンスを生成する必要がある。MinhonServiceのインスタンスを生成しようとしたら、okHttpClientのインスタンスを設定する必要がある。以下、ループ。
本来は、分けているのがSpringFWの思想的に正しそうな気がするが、実装するときにクラス作るのが面倒で、同じクラスに書いたら、この問題を踏んだ。。。
解消方法
生成と利用箇所を分けるように実装した。
具体的には、以下の通り
@Service @Component public class MinhonService { // ・・・・ @Autowired OkHttpClient client; @Autowired private RestTemplate restTemplate; // ・・・・ }
@Configuration public class MinhonBeanConfig { @Bean public OkHttpClient okHttpClient() { return new OkHttpClient(); } @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }
たぶん、本来あるべき姿はこうなのだろう。
なぜ、一緒にしていても動いていたのかは不明。。。
あきらかに沼りそうだから、調べたくはないってのが本音。