Issue
Following this post, I configured
(1) a Eureka Server,
(2) a toll rate service which is a client of (1),
(3) a toll rate dashboard which read data from (2).
It went well until I made some changes using @LoadBalanced (maybe it is not exactly due to load balancer, but I'll post related code chunks below)
In bootstrap.properties in (2), the common endpoint name is
spring.application.name = demo-tollrate-service
In DashboardController.java in (3), as you can see the HTTP address is changed to above application name
// import some libraries
@Controller
public class DashboardController {
@Autowired
private RestTemplate restTemplate;
@LoadBalanced
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@RequestMapping("/dashboard")
public String GetTollRate(@RequestParam int stationId, Model m) {
TollRate tr = restTemplate.getForObject("http://demo-tollrate-service/tollrate/" + stationId, TollRate.class);
m.addAttribute("rate", tr.getCurrentRate());
return "dashboard";
}
}
The pom.xml is roughly the same in this post
When running this app, I got the below errors.
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌──->──┐
| dashboardController (field private org.springframework.web.client.RestTemplate com.example.demo.DashboardController.restTemplate)
└──<-──┘
Action:
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
Can anyone please help me here? Thank you.
Solution
It has a circular dependency, the DashboardController depends on the RestTemplate, but the RestTemplate is defined inside the DashboardController.
The Java version does not make any difference, but maybe the Spring version. The new Spring version is not allowing circular references by default. You can change that adding a property in the application.properties file, here you can find more details:
But I recommend a refactor, there is no good reason to define the RestTemplate inside the controller, it is much better to do it in a @Configuration class.
Answered By - Eduardo Felipe Zambom Santana