The RestTemplate bean will be intercepted and auto-configured by Spring Cloud (due to the @LoadBalanced annotation) to use a custom HttpRequestClient that uses Netflix Ribbon to do the microservice lookup. Ribbon is also a load balancer, so if you have multiple instances of a service available, it picks one for you. (Neither Eureka nor Consul on their own performs load balancing, so we use Ribbon to do it instead.)
The loadBalancer takes the logical service name (as registered with the discovery server) and converts it to the actual hostname of the chosen microservice. A RestTemplate instance is thread-safe and can be used to access any number of services in different parts of your application.
Let's see the configuration file of this web application:
spring: application: name: web-application server: port: 6464 eureka: client: service-url: default-zone: ${EUREKA_URI:http://localhost:8761/eureka} instance: prefer-ip-address: true
After configuration file creation, let's run this main application class and see the following Eureka dashboard:
As you can see, WEB-APPLICATION is registered with the Eureka discovery service. Let's see the WebAccountService class, which accesses the account microservice by using names rather than server addresses:
package com.dineshonjava.webapplication.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import com.dineshonjava.webapplication.domain.Account; import com.dineshonjava.webapplication.exception.AccountNotFoundException; @Service public class WebAccountsService { @Autowired protected RestTemplate restTemplate; // ACCOUNTS-SERVICE is the name of the microservice we're calling protected String serviceUrl = "http://ACCOUNT-SERVICE"; public Account getByNumber(String accountNumber) { Account account = restTemplate.getForObject(serviceUrl + "/account/{accountId}", Account.class, accountNumber); if (account == null) throw new AccountNotFoundException(accountNumber); else return account; } public List<Account> getAllAccounts(){ return restTemplate.getForObject(serviceUrl+ "/account", List.class); } ... ... }
The service class accesses the backend microservice for this web application. The @LoadBalanced annotated RestTemplate will resolve application names (ACCOUNT-SERVICE) to a real server name and port by querying Eureka. The @LoadBalanced annotation tells Spring Boot to customize RestTemplate with ClientHttpRequestFactory that does a Eureka lookup before making the HTTP call. To make this work, you'll need to add a new config setting to application.properties:
ribbon.http.client.enabled=true
You can find complete web application from GitHub (https://github.com/PacktPublishing/Mastering-Spring-Boot-2.0 ).
Let's discuss the Spring Data project of the Spring Framework in the next section.