In my Config class I have bean with RestTemplate and I had to add CurrencyConverterService currencyConverter becoues I am using it in modelMapper. Config class:
@Configuration
@RequiredArgsConstructor
public class Config {
private final CurrencyConverterService currencyConverter;
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
... }
but in currencyConverter I have to use RestTemplate to get current currency rates from api so I added RestTemplate:
@Service
@RequiredArgsConstructor
public class CurrencyConverterService {
private static String BASE_URL = url...;
private final RestTemplate restTemplate;
private final CurrencyEntityRepository currencyEntityRepository;
and of course I am getting error:
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| config defined in file [C:\config\Config.class]
↑ ↓
| currencyConverterService defined in file [C\service\CurrencyConverterService.class]
└─────┘
I was trying to add @Lazy up to restTemplate in CurrencyService but it does not help.
spring.main.allow-circular-references= true did not help too
CodePudding user response:
What about
@Configuration
public class Config {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public ModelMapper modelMapper(final CurrencyConverterService currencyConverter) {
ModelMapper modelMapper = new ModelMapper();
...
}
...
}
when you create a bean you can pass other beans as parameter
CodePudding user response:
Solution 1: use javax.inject.Provider
Assuming you are using Maven you can add the following dependency:
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
And then in CurrencyConverterService inject an instance of javax.inject.Provider
of RestTemplate
:
import javax.inject.Provider;
...
@Service
@RequiredArgsConstructor
public class CurrencyConverterService {
...
private final Provider<RestTemplate> restTemplate;
And retrieve the instance with restTemplate.get()
.
However this will still fail during runtime in case of circular usage.
Solution 2: resolve cyclic dependency
Assuming you do not need the CurrencyConverterService
for constructing RestTemplate
the more stable solution is to create a second class producing the RestTemaplate
(you can have as many classes annotated with @Configuration
or @Component
as you want):
@Configuration
public class RestTemplateProducer {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}