Writing Client Applications

Refer to the sample applications in the “traveler” repository to follow along with the code in this topic.

To use Spring Cloud Netflix Hystrix circuit breakers in a Spring Boot app with a Circuit Breaker Dashboard instance, you must add the dependencies listed below.

Important: Ensure that the ordering of the Maven BOM dependencies listed below is preserved in your application’s build file. Dependency resolution is affected in both Maven and Gradle by the order in which dependencies are declared.

To work with Spring Cloud Services service instances, your client application must include the following BOMs:

  • spring-cloud-services-dependencies
  • spring-cloud-dependencies
  • spring-boot-dependencies, unless you use spring-boot-starter-parent (with Maven) or the Spring Boot Gradle plugin (with Gradle)

See the following sections for how to construct a build file for your use case.

General Dependencies

Construct your build file using one of the examples below, for either Maven or Gradle. Replace [BOOT], [CLOUD], and [SCS] according to your Spring Boot and Spring Cloud version. Refer to the following table:

If using… …use [BOOT] …use [CLOUD] …use [SCS]
Boot 2, Cloud Finchley 2.0.3.RELEASE Finchley.RELEASE 2.0.1.RELEASE
Boot 1.5, Cloud Edgware 1.5.13.RELEASE Edgware.SR3 1.6.1.RELEASE

For Maven

If using Maven, include in pom.xml:

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>[BOOT]</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.pivotal.spring.cloud</groupId>
            <artifactId>spring-cloud-services-dependencies</artifactId>
            <version>[SCS]</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>[CLOUD]</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
  </dependencyManagement>

If not using the spring-boot-starter-parent, include in the <dependencyManagement> block of pom.xml:

  <dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>[BOOT]</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <!-- ... -->

    </dependencies>
  </dependencyManagement>

For Gradle

If using Gradle, you will also need to use the Gradle dependency management plugin.

Include in build.gradle:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("io.spring.gradle:dependency-management-plugin:1.0.5.RELEASE")
        classpath("org.springframework.boot:spring-boot-gradle-plugin:[BOOT]")
    }
}

apply plugin: "java"
apply plugin: "org.springframework.boot"
apply plugin: "io.spring.dependency-management"

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:[CLOUD]"
        mavenBom "io.pivotal.spring.cloud:spring-cloud-services-dependencies:[SCS]"
    }
}

repositories {
    maven {
        url "https://repo.spring.io/plugins-release"
    }
}

If not using the Spring Boot Gradle plugin, include in the dependencyManagement block of build.gradle:

dependencyManagement {
    imports {
        mavenBom "org.springframework.boot:spring-boot-dependencies:[BOOT]"
    }
}

Your app must also declare the Spring Cloud Services Circuit Breaker Dashboard starter as a dependency.

If using Maven, include in pom.xml:

  <dependencies>
    <dependency>
      <groupId>io.pivotal.spring.cloud</groupId>
      <artifactId>spring-cloud-services-starter-circuit-breaker</artifactId>
    </dependency>
  </dependencies>

If using Gradle, include in build.gradle:

dependencies {
    compile("io.pivotal.spring.cloud:spring-cloud-services-starter-circuit-breaker")
}

Use a Circuit Breaker

To work with a Circuit Breaker Dashboard instance, your application must include the @EnableCircuitBreaker annotation on a configuration class.

import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
//...

@SpringBootApplication
@EnableDiscoveryClient
@RestController
@EnableCircuitBreaker
public class AgencyApplication {
    //...

To apply a circuit breaker to a method, annotate the method with @HystrixCommand, giving the annotation the name of a fallbackMethod.

    @HystrixCommand(fallbackMethod = "getBackupGuide")
    public String getGuide() {
        return restTemplate.getForObject("http://company/available", String.class);
    }

The getGuide() method uses a RestTemplate to obtain a guide name from another application called Company, which is registered with a Service Registry instance. (See the Service Registry documentation, specifically the Writing Client Applications topic.) The method thus relies on the Company application to return a response, and if the Company application fails to do so, calls to getGuide() will fail. When the failures exceed the threshold, the breaker on getGuide() will open the circuit.

While the circuit is open, the breaker redirects calls to the annotated method, and they instead call the designated fallbackMethod. The fallback method must be in the same class and have the same method signature (i.e., have the same return type and accept the same parameters) as the annotated method. In the Agency application, the getGuide() method on the TravelAgent class falls back to getBackupGuide().

    String getBackupGuide() {
        return "None available! Your backup guide is: Cookie";
    }

If you wish, you may also annotate fallback methods themselves with @HystrixCommand to create a fallback chain.

Use a Circuit Breaker with a Feign Client

If you want to use a Spring Cloud Feign client with Hystrix circuit breakers, set the feign.hystrix.enabled property to true. In the Feign version of the Agency app, this property is configured in application.yml:

feign:
  hystrix:
    enabled: true

To provide a circuit breaker on a Feign client, you must specify a fallback class using a fallback attribute in the @FeignClient annotation on the client interface. Fallback methods must be Spring beans. In the Feign version of the Agency app, the CompanyClient interface uses a CompanyFallback class, which is annotated with @Component:

@FeignClient(name = "company", fallback = CompanyClient.CompanyFallback.class)
public interface CompanyClient {
  @RequestMapping(method = GET, value="/available")
  String availableGuide();

@Component
  public static class CompanyFallback implements CompanyClient {
    @Override
    public String availableGuide() {
      return "None available!";
    }
  }
}

The AgencyApplication class is annotated with @EnableFeignClients:

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableFeignClients
public class AgencyApplication {
    //...

If the Company app becomes unavailable or if the Agency app cannot access it, calls to the Company app through the client’s availableGuide() method will fail. When successive failures build up to the threshold, Hystrix will open the circuit, and subsequent calls will be redirected to the fallback class’s method until the Company app is accessible again and the circuit is closed.

Create a pull request or raise an issue on the source for this page in GitHub