<title>2. Spring Cloud Commons: Common Abstractions</title><linkrel="stylesheet"type="text/css"href="css/manual-multipage.css"><metaname="generator"content="DocBook XSL Stylesheets V1.78.1"><linkrel="home"href="multi_spring-cloud-commons.html"title="Cloud Native Applications"><linkrel="up"href="multi_spring-cloud-commons.html"title="Cloud Native Applications"><linkrel="prev"href="multi__spring_cloud_context_application_context_services.html"title="1. Spring Cloud Context: Application Context Services"></head><bodybgcolor="white"text="black"link="#0000FF"vlink="#840084"alink="#0000FF"><divclass="navheader"><tablewidth="100%"summary="Navigation header"><tr><thcolspan="3"align="center">2. Spring Cloud Commons: Common Abstractions</th></tr><tr><tdwidth="20%"align="left"><aaccesskey="p"href="multi__spring_cloud_context_application_context_services.html">Prev</a> </td><thwidth="60%"align="center"> </th><tdwidth="20%"align="right"> </td></tr></table><hr></div><divclass="chapter"><divclass="titlepage"><div><div><h1class="title"><aname="_spring_cloud_commons_common_abstractions"href="#_spring_cloud_commons_common_abstractions"></a>2. Spring Cloud Commons: Common Abstractions</h1></div></div></div><p>Patterns such as service discovery, load balancing, and circuit breakers lend themselves to a common abstraction layer that can be consumed by all Spring Cloud clients, independent of the implementation (for example, discovery with Eureka or Consul).</p><divclass="section"><divclass="titlepage"><div><div><h2class="title"style="clear: both"><aname="__enablediscoveryclient"href="#__enablediscoveryclient"></a>2.1 @EnableDiscoveryClient</h2></div></div></div><p>Spring Cloud Commons provides the <codeclass="literal">@EnableDiscoveryClient</code> annotation.
This looks for implementations of the <codeclass="literal">DiscoveryClient</code> interface with <codeclass="literal">META-INF/spring.factories</code>.
Implementations of the Discovery Client add a configuration class to <codeclass="literal">spring.factories</code> under the <codeclass="literal">org.springframework.cloud.client.discovery.EnableDiscoveryClient</code> key.
Examples of <codeclass="literal">DiscoveryClient</code> implementations include <aclass="link"href="http://cloud.spring.io/spring-cloud-netflix/"target="_top">Spring Cloud Netflix Eureka</a>, <aclass="link"href="http://cloud.spring.io/spring-cloud-consul/"target="_top">Spring Cloud Consul Discovery</a>, and <aclass="link"href="http://cloud.spring.io/spring-cloud-zookeeper/"target="_top">Spring Cloud Zookeeper Discovery</a>.</p><p>By default, implementations of <codeclass="literal">DiscoveryClient</code> auto-register the local Spring Boot server with the remote discovery server.
This behavior can be disabled by setting <codeclass="literal">autoRegister=false</code> in <codeclass="literal">@EnableDiscoveryClient</code>.</p><divclass="note"style="margin-left: 0.5in; margin-right: 0.5in;"><tableborder="0"summary="Note"><tr><tdrowspan="2"align="center"valign="top"width="25"><imgalt="[Note]"src="images/note.png"></td><thalign="left">Note</th></tr><tr><tdalign="left"valign="top"><p><codeclass="literal">@EnableDiscoveryClient</code> is no longer required.
You can put a <codeclass="literal">DiscoveryClient</code> implementation on the classpath to cause the Spring Boot application to register with the service discovery server.</p></td></tr></table></div><divclass="section"><divclass="titlepage"><div><div><h3class="title"><aname="_health_indicator"href="#_health_indicator"></a>2.1.1 Health Indicator</h3></div></div></div><p>Commons creates a Spring Boot <codeclass="literal">HealthIndicator</code> that <codeclass="literal">DiscoveryClient</code> implementations can participate in by implementing <codeclass="literal">DiscoveryHealthIndicator</code>.
To disable the composite <codeclass="literal">HealthIndicator</code>, set <codeclass="literal">spring.cloud.discovery.client.composite-indicator.enabled=false</code>.
A generic <codeclass="literal">HealthIndicator</code> based on <codeclass="literal">DiscoveryClient</code> is auto-configured (<codeclass="literal">DiscoveryClientHealthIndicator</code>).
To disable it, set <codeclass="literal">spring.cloud.discovery.client.health-indicator.enabled=false</code>.
To disable the description field of the <codeclass="literal">DiscoveryClientHealthIndicator</code>, set <codeclass="literal">spring.cloud.discovery.client.health-indicator.include-description=false</code>.
Otherwise, it can bubble up as the <codeclass="literal">description</code> of the rolled up <codeclass="literal">HealthIndicator</code>.</p></div></div><divclass="section"><divclass="titlepage"><div><div><h2class="title"style="clear: both"><aname="_serviceregistry"href="#_serviceregistry"></a>2.2 ServiceRegistry</h2></div></div></div><p>Commons now provides a <codeclass="literal">ServiceRegistry</code> interface that provides methods such as <codeclass="literal">register(Registration)</code> and <codeclass="literal">deregister(Registration)</code>, which let you provide custom registered services.
<codeclass="literal">Registration</code> is a marker interface.</p><p>The following example shows the <codeclass="literal">ServiceRegistry</code> in use:</p><preclass="programlisting"><em><spanclass="hl-annotation"style="color: gray">@Configuration</span></em>
<spanxmlns:d="http://docbook.org/ns/docbook"class="hl-comment">// called through some external process, such as an event or a custom actuator endpoint</span>
}</pre><p>Each <codeclass="literal">ServiceRegistry</code> implementation has its own <codeclass="literal">Registry</code> implementation.</p><divclass="itemizedlist"><ulclass="itemizedlist"style="list-style-type: disc; "><liclass="listitem"><codeclass="literal">ZookeeperRegistration</code> used with <codeclass="literal">ZookeeperServiceRegistry</code></li><liclass="listitem"><codeclass="literal">EurekaRegistration</code> used with <codeclass="literal">EurekaServiceRegistry</code></li><liclass="listitem"><codeclass="literal">ConsulRegistration</code> used with <codeclass="literal">ConsulServiceRegistry</code></li></ul></div><p>If you are using the <codeclass="literal">ServiceRegistry</code> interface, you are going to need to pass the
correct <codeclass="literal">Registry</code> implementation for the <codeclass="literal">ServiceRegistry</code> implementation you
are using.</p><divclass="section"><divclass="titlepage"><div><div><h3class="title"><aname="_serviceregistry_auto_registration"href="#_serviceregistry_auto_registration"></a>2.2.1 ServiceRegistry Auto-Registration</h3></div></div></div><p>By default, the <codeclass="literal">ServiceRegistry</code> implementation auto-registers the running service.
* <codeclass="literal">@EnableDiscoveryClient(autoRegister=false)</code> to permanently disable auto-registration.
* <codeclass="literal">spring.cloud.service-registry.auto-registration.enabled=false</code> to disable the behavior through configuration.</p></div><divclass="section"><divclass="titlepage"><div><div><h3class="title"><aname="_service_registry_actuator_endpoint"href="#_service_registry_actuator_endpoint"></a>2.2.2 Service Registry Actuator Endpoint</h3></div></div></div><p>Spring Cloud Commons provides a <codeclass="literal">/service-registry</code> actuator endpoint.
This endpoint relies on a <codeclass="literal">Registration</code> bean in the Spring Application Context.
Calling <codeclass="literal">/service-registry</code> with GET returns the status of the <codeclass="literal">Registration</code>.
Using POST to the same endpoint with a JSON body changes the status of the current <codeclass="literal">Registration</code> to the new value.
The JSON body has to include the <codeclass="literal">status</code> field with the preferred value.
Please see the documentation of the <codeclass="literal">ServiceRegistry</code> implementation you use for the allowed values when updating the status and the values returned for the status.
For instance, Eureka’s supported statuses are <codeclass="literal">UP</code>, <codeclass="literal">DOWN</code>, <codeclass="literal">OUT_OF_SERVICE</code>, and <codeclass="literal">UNKNOWN</code>.</p></div></div><divclass="section"><divclass="titlepage"><div><div><h2class="title"style="clear: both"><aname="_spring_resttemplate_as_a_load_balancer_client"href="#_spring_resttemplate_as_a_load_balancer_client"></a>2.3 Spring RestTemplate as a Load Balancer Client</h2></div></div></div><p><codeclass="literal">RestTemplate</code> can be automatically configured to use ribbon.
To create a load-balanced <codeclass="literal">RestTemplate</code>, create a <codeclass="literal">RestTemplate</code><codeclass="literal">@Bean</code> and use the <codeclass="literal">@LoadBalanced</code> qualifier, as shown in the following example:</p><preclass="programlisting"><em><spanclass="hl-annotation"style="color: gray">@Configuration</span></em>
}</pre><divclass="caution"style="margin-left: 0.5in; margin-right: 0.5in;"><tableborder="0"summary="Caution"><tr><tdrowspan="2"align="center"valign="top"width="25"><imgalt="[Caution]"src="images/caution.png"></td><thalign="left">Caution</th></tr><tr><tdalign="left"valign="top"><p>A <codeclass="literal">RestTemplate</code> bean is no longer created through auto-configuration.
Individual applications must create it.</p></td></tr></table></div><p>The URI needs to use a virtual host name (that is, a service name, not a host name).
The Ribbon client is used to create a full physical address.
See <aclass="link"href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java"target="_top">RibbonAutoConfiguration</a> for details of how the <codeclass="literal">RestTemplate</code> is set up.</p></div><divclass="section"><divclass="titlepage"><div><div><h2class="title"style="clear: both"><aname="_spring_webclient_as_a_load_balancer_client"href="#_spring_webclient_as_a_load_balancer_client"></a>2.4 Spring WebClient as a Load Balancer Client</h2></div></div></div><p><codeclass="literal">WebClient</code> can be automatically configured to use the <codeclass="literal">LoadBalancerClient</code>.
To create a load-balanced <codeclass="literal">WebClient</code>, create a <codeclass="literal">WebClient.Builder</code><codeclass="literal">@Bean</code> and use the <codeclass="literal">@LoadBalanced</code> qualifier, as shown in the following example:</p><preclass="programlisting"><em><spanclass="hl-annotation"style="color: gray">@Configuration</span></em>
}</pre><p>The URI needs to use a virtual host name (that is, a service name, not a host name).
The Ribbon client is used to create a full physical address.</p><divclass="section"><divclass="titlepage"><div><div><h3class="title"><aname="_retrying_failed_requests"href="#_retrying_failed_requests"></a>2.4.1 Retrying Failed Requests</h3></div></div></div><p>A load-balanced <codeclass="literal">RestTemplate</code> can be configured to retry failed requests.
By default, this logic is disabled.
You can enable it by adding <aclass="link"href="https://github.com/spring-projects/spring-retry"target="_top">Spring Retry</a> to your application’s classpath.
The load-balanced <codeclass="literal">RestTemplate</code> honors some of the Ribbon configuration values related to retrying failed requests.
You can use <codeclass="literal">client.ribbon.MaxAutoRetries</code>, <codeclass="literal">client.ribbon.MaxAutoRetriesNextServer</code>, and <codeclass="literal">client.ribbon.OkToRetryOnAllOperations</code> properties.
If you would like to disable the retry logic with Spring Retry on the classpath, you can set <codeclass="literal">spring.cloud.loadbalancer.retry.enabled=false</code>.
See the <aclass="link"href="https://github.com/Netflix/ribbon/wiki/Getting-Started#the-properties-file-sample-clientproperties"target="_top">Ribbon documentation</a> for a description of what these properties do.</p><p>If you would like to implement a <codeclass="literal">BackOffPolicy</code> in your retries, you need to create a bean of type <codeclass="literal">LoadBalancedBackOffPolicyFactory</code> and return the <codeclass="literal">BackOffPolicy</code> you would like to use for a given service, as shown in the following example:</p><preclass="programlisting"><em><spanclass="hl-annotation"style="color: gray">@Configuration</span></em>
}</pre><divclass="note"style="margin-left: 0.5in; margin-right: 0.5in;"><tableborder="0"summary="Note"><tr><tdrowspan="2"align="center"valign="top"width="25"><imgalt="[Note]"src="images/note.png"></td><thalign="left">Note</th></tr><tr><tdalign="left"valign="top"><p><codeclass="literal">client</code> in the preceding examples should be replaced with your Ribbon client’s name.</p></td></tr></table></div><p>If you want to add one or more <codeclass="literal">RetryListener</code> implementations to your retry functionality, you need to
you would like to use for a given service, as shown in the following example:</p><preclass="programlisting"><em><spanclass="hl-annotation"style="color: gray">@Configuration</span></em>
}</pre></div></div><divclass="section"><divclass="titlepage"><div><div><h2class="title"style="clear: both"><aname="_multiple_resttemplate_objects"href="#_multiple_resttemplate_objects"></a>2.5 Multiple RestTemplate objects</h2></div></div></div><p>If you want a <codeclass="literal">RestTemplate</code> that is not load-balanced, create a <codeclass="literal">RestTemplate</code> bean and inject it.
To access the load-balanced <codeclass="literal">RestTemplate</code>, use the <codeclass="literal">@LoadBalanced</code> qualifier when you create your <codeclass="literal">@Bean</code>, as shown in the following example:\</p><preclass="programlisting"><em><spanclass="hl-annotation"style="color: gray">@Configuration</span></em>
}</pre><divclass="important"style="margin-left: 0.5in; margin-right: 0.5in;"><tableborder="0"summary="Important"><tr><tdrowspan="2"align="center"valign="top"width="25"><imgalt="[Important]"src="images/important.png"></td><thalign="left">Important</th></tr><tr><tdalign="left"valign="top"><p>Notice the use of the <codeclass="literal">@Primary</code> annotation on the plain <codeclass="literal">RestTemplate</code> declaration in the preceding example to disambiguate the unqualified <codeclass="literal">@Autowired</code> injection.</p></td></tr></table></div><divclass="tip"style="margin-left: 0.5in; margin-right: 0.5in;"><tableborder="0"summary="Tip"><tr><tdrowspan="2"align="center"valign="top"width="25"><imgalt="[Tip]"src="images/tip.png"></td><thalign="left">Tip</th></tr><tr><tdalign="left"valign="top"><p>If you see errors such as <codeclass="literal">java.lang.IllegalArgumentException: Can not set org.springframework.web.client.RestTemplate field com.my.app.Foo.restTemplate to com.sun.proxy.$Proxy89</code>, try injecting <codeclass="literal">RestOperations</code> or setting <codeclass="literal">spring.aop.proxyTargetClass=true</code>.</p></td></tr></table></div></div><divclass="section"><divclass="titlepage"><div><div><h2class="title"style="clear: both"><aname="loadbalanced-webclient"href="#loadbalanced-webclient"></a>2.6 Spring WebFlux WebClient as a Load Balancer Client</h2></div></div></div><p><codeclass="literal">WebClient</code> can be configured to use the <codeclass="literal">LoadBalancerClient</code>. <codeclass="literal">LoadBalancerExchangeFilterFunction</code> is auto-configured if <codeclass="literal">spring-webflux</code> is on the classpath. The following example shows how to configure a <codeclass="literal">WebClient</code> to use load balancer:</p><preclass="programlisting"><spanxmlns:d="http://docbook.org/ns/docbook"class="hl-keyword">public</span><spanxmlns:d="http://docbook.org/ns/docbook"class="hl-keyword">class</span> MyClass {
}</pre><p>The URI needs to use a virtual host name (that is, a service name, not a host name).
The <codeclass="literal">LoadBalancerClient</code> is used to create a full physical address.</p></div><divclass="section"><divclass="titlepage"><div><div><h2class="title"style="clear: both"><aname="ignore-network-interfaces"href="#ignore-network-interfaces"></a>2.7 Ignore Network Interfaces</h2></div></div></div><p>Sometimes, it is useful to ignore certain named network interfaces so that they can be excluded from Service Discovery registration (for example, when running in a Docker container).
A list of regular expressions can be set to cause the desired network interfaces to be ignored.
The following configuration ignores the <codeclass="literal">docker0</code> interface and all interfaces that start with <codeclass="literal">veth</code>:</p><p><b>application.yml. </b>
</p><p>You can also force the use of only specified network addresses by using a list of regular expressions, as shown in the following example:</p><p><b>bootstrap.yml. </b>
useOnlySiteLocalInterfaces: true</pre><p>See <aclass="link"href="https://docs.oracle.com/javase/8/docs/api/java/net/Inet4Address.html#isSiteLocalAddress--"target="_top">Inet4Address.html.isSiteLocalAddress()</a> for more details about what constitutes a site-local address.</p></div><divclass="section"><divclass="titlepage"><div><div><h2class="title"style="clear: both"><aname="http-clients"href="#http-clients"></a>2.8 HTTP Client Factories</h2></div></div></div><p>Spring Cloud Commons provides beans for creating both Apache HTTP clients (<codeclass="literal">ApacheHttpClientFactory</code>) and OK HTTP clients (<codeclass="literal">OkHttpClientFactory</code>).
The <codeclass="literal">OkHttpClientFactory</code> bean is created only if the OK HTTP jar is on the classpath.
In addition, Spring Cloud Commons provides beans for creating the connection managers used by both clients: <codeclass="literal">ApacheHttpClientConnectionManagerFactory</code> for the Apache HTTP client and <codeclass="literal">OkHttpClientConnectionPoolFactory</code> for the OK HTTP client.
If you would like to customize how the HTTP clients are created in downstream projects, you can provide your own implementation of these beans.
In addition, if you provide a bean of type <codeclass="literal">HttpClientBuilder</code> or <codeclass="literal">OkHttpClient.Builder</code>, the default factories use these builders as the basis for the builders returned to downstream projects.
You can also disable the creation of these beans by setting <codeclass="literal">spring.cloud.httpclientfactories.apache.enabled</code> or <codeclass="literal">spring.cloud.httpclientfactories.ok.enabled</code> to <codeclass="literal">false</code>.</p></div><divclass="section"><divclass="titlepage"><div><div><h2class="title"style="clear: both"><aname="enabled-features"href="#enabled-features"></a>2.9 Enabled Features</h2></div></div></div><p>Spring Cloud Commons provides a <codeclass="literal">/features</code> actuator endpoint.
This endpoint returns features available on the classpath and whether they are enabled.
The information returned includes the feature type, name, version, and vendor.</p><divclass="section"><divclass="titlepage"><div><div><h3class="title"><aname="_feature_types"href="#_feature_types"></a>2.9.1 Feature types</h3></div></div></div><p>There are two types of 'features': abstract and named.</p><p>Abstract features are features where an interface or abstract class is defined and that an implementation the creates, such as <codeclass="literal">DiscoveryClient</code>, <codeclass="literal">LoadBalancerClient</code>, or <codeclass="literal">LockService</code>.
The abstract class or interface is used to find a bean of that type in the context.
The version displayed is <codeclass="literal">bean.getClass().getPackage().getImplementationVersion()</code>.</p><p>Named features are features that do not have a particular class they implement, such as "Circuit Breaker", "API Gateway", "Spring Cloud Bus", and others. These features require a name and a bean type.</p></div><divclass="section"><divclass="titlepage"><div><div><h3class="title"><aname="_declaring_features"href="#_declaring_features"></a>2.9.2 Declaring features</h3></div></div></div><p>Any module can declare any number of <codeclass="literal">HasFeature</code> beans, as shown in the following examples:</p><preclass="programlisting"><em><spanclass="hl-annotation"style="color: gray">@Bean</span></em>
}</pre><p>Each of these beans should go in an appropriately guarded <codeclass="literal">@Configuration</code>.</p></div></div></div><divclass="navfooter"><hr><tablewidth="100%"summary="Navigation footer"><tr><tdwidth="40%"align="left"><aaccesskey="p"href="multi__spring_cloud_context_application_context_services.html">Prev</a> </td><tdwidth="20%"align="center"> </td><tdwidth="40%"align="right"> </td></tr><tr><tdwidth="40%"align="left"valign="top">1. Spring Cloud Context: Application Context Services </td><tdwidth="20%"align="center"><aaccesskey="h"href="multi_spring-cloud-commons.html">Home</a></td><tdwidth="40%"align="right"valign="top"> </td></tr></table></div></body></html>