Reputation: 271
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
Upvotes: 0
Views: 465
Reputation: 407
You can write @Lazy at the top of the @Autowired in of the class where you are injecting dependencies. As that will break the cycle. However you have to write it on the top of @Autowired
Upvotes: 0
Reputation: 872
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.
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();
}
}
Upvotes: 0
Reputation: 6936
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
Upvotes: 1