Cloud Native is a style of application development that encourages easy adoption of best practices in the areas of continuous delivery and value-driven development. A related discipline is that of building 12-factor Applications, in which development practices are aligned with delivery and operations goals — for instance, by using declarative programming and management and monitoring. Spring Cloud facilitates these styles of development in a number of specific ways. The starting point is a set of features to which all components in a distributed system need easy access.
Many of those features are covered by Spring Boot, on which Spring Cloud builds. Some more features are delivered by Spring Cloud as two libraries: Spring Cloud Context and Spring Cloud Commons.
Spring Cloud Context provides utilities and special services for the ApplicationContext
of a Spring Cloud application (bootstrap context, encryption, refresh scope, and environment endpoints). Spring Cloud Commons is a set of abstractions and common classes used in different Spring Cloud implementations (such Spring Cloud Consul).
If you get an exception due to "Illegal key size" and you use Sun’s JDK, you need to install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. See the following links for more information:
Extract the files into the JDK/jre/lib/security folder for whichever version of JRE/JDK x64/x86 you use.
Spring Cloud is released under the non-restrictive Apache 2.0 license. If you want to contribute to this section of the documentation or if you find an error, you can find the source code and issue trackers for the project at GitHub. |
Spring Cloud Square provides Spring Cloud LoadBalancer integration for OkHttpClient and Retrofit, as well as a WebClient-backed Retrofit clients.
1. Quick Start
This quick start walks through using SC LoadBalancer OkHttpClient integration, load-balanced OkHttpClient-based Retrofit clients, and load-balanced WebClient-based Retrofit clients.
1.1. OkHttpClient with Spring Cloud LoadBalancer
First, add the spring-cloud-square-okhttp
dependency to your project:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-square-okhttp</artifactId>
<version>0.4.1</version>
</dependency>
Then create a @LoadBalanced
-annotated OkHttpClient.Builder
bean:
@Configuration
class OkHttpClientConfig{
@Bean
@LoadBalanced
public OkHttpClient.Builder okHttpClientBuilder() {
return new OkHttpClient.Builder();
}
}
Now you can use the serviceId
or virtual hostname rather than an actual host:port
in your requests — SC LoadBalancer resolves it by selecting one of the available service instances.
Request request = new Request.Builder()
.url("http://serviceId/hello").build();
Response response = builder.build().newCall(request).execute();
1.2. Retrofit with OkHttpClient and Spring Cloud LoadBalancer
First, add the spring-cloud-square-retrofit
and spring-cloud-square-okhttp
dependencies to your project:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-square-retrofit</artifactId>
<version>0.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-square-okhttp</artifactId>
<version>0.4.1</version>
</dependency>
</dependencies>
Use the @EnableRetrofitClients
annotation to let us automatically instantiate and inject Retrofit clients for you. Then create a @LoadBalanced
-annotated OkHttpClient.Builder
bean to be used under the hood:
@Configuration
@EnableRetrofitClients
class OkHttpClientConfig {
@Bean
@LoadBalanced
public OkHttpClient.Builder okHttpClientBuilder() {
return new OkHttpClient.Builder();
}
}
Create a Retrofit client and annotate it with @RetrofitClient
, passing the serviceId
of your service as argument (the annotation can also be used to pass a custom configuration that contains user-crated interceptors for the Retrofit client):
@RetrofitClient("serviceId")
interface HelloClient {
@GET("/")
Call<String> hello();
}
Make sure to use Retrofit method annotations, such as @GET("/")
.
You can now inject the Retrofit client and use it to run load-balanced calls (by using serviceId
instead of actual host:port
):
class AService {
@Autowired
HelloClient client;
public String hello() throws IOException {
return client.hello().execute().body();
}
}
We created a full sample for load-balanced-OkHttpClient-based Retrofit clients.
1.3. Retrofit with WebClient and Spring Cloud LoadBalancer
First, add the spring-cloud-square-retrofit
and spring-boot-starter-webflux
starter dependencies to your project:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-square-retrofit</artifactId>
<version>0.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
</dependencies>
Use the @EnableRetrofitClients
annotation to let us automatically instantiate and inject Retrofit clients for you. Then create a @LoadBalanced
-annotated WebClient.Builder
bean to be used under the hood:
@Configuration
@EnableRetrofitClients
class OkHttpClientConfig {
@Bean
@LoadBalanced
public WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
}
Create a Retrofit client and annotate it with @RetrofitClient
, passing the serviceId
of your service as argument:
@RetrofitClient("serviceId")
interface HelloClient {
@GET("/")
Mono<String> hello();
}
Make sure to use Retrofit method annotations, such as @GET("/")
.
You can now inject the Retrofit client and use it to run load-balanced calls (by using serviceId
instead of actual host:port
):
class AService {
@Autowired
HelloClient client;
public Mono<String> hello() throws IOException {
return client.hello();
}
}
We created a full sample for load-balanced-WebClient-based Retrofit clients.
As the currently available release is a milestone, you need to add the Spring Milestone repository link to your projects for all the examples presented in this blog entry: |
<repositories>
<repository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
We recommend using dependency management for other Spring Cloud dependencies:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2. OkHttpClient Spring Cloud LoadBalancer Integration
An interceptor is added to the OkHttpClient
created by auto-configuration to resolve the scheme, host, and port from Spring Cloud LoadBalancer and rewrite the URL.
You can access this functionality by annotating OkHttpClient.Builder
beans with @LoadBalanced
:
@Configuration
class OkHttpClientConfig{
@Bean
@LoadBalanced
public OkHttpClient.Builder okHttpClientBuilder() {
return new OkHttpClient.Builder();
}
}
Then you can use the serviceId
or virtual hostname rather than an actual host:port
in your requests — SC LoadBalancer resolves it by selecting one of the available service instances:
Request request = new Request.Builder()
.url("http://serviceId/hello").build();
Response response = builder.build().newCall(request).execute();
You can also use the @LoadBalancerClient
and @LoadBalancerClients
annotations to pass custom configuration to load-balanced OkHttpClient instances.
This integration supports all the LoadBalancer features. You can read more about them in the https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#spring-cloud-loadbalancer[Spring Cloud Commons documentation].
You can also disable OkHttpClient load-balancing via properties, by setting the value of spring.cloud.square.okhttp.loadbalancer.enabled
to false
.
3. Retrofit Integration
We provide Spring Boot and Spring Cloud LoadBalancer integration for Retrofit, which is a declarative HTTP client from Square.
To enable and instantiate Retrofit clients, use the @EnableRetrofitClients
annotation over a Spring @Configuration
class:
@EnableRetrofitClients(clients = TestClient.class, defaultConfiguration = LoggingRetrofitConfig.class)
@Configuration
class AppConfiguration{
}
It scans for interfaces that declare they are clients (through @RetrofitClient
). You can further control the scope of the scan by specifying packages or client names in the annotation parameters. You can also use the defaultConfiguration
parameter to specify the default config class for all your Retrofit clients.
You can create load-balanced Retrofit client beans by annotating a Retrofit interface with @RetrofitClient
.
The next two listings show examples. The first one uses an OkHttpClient
-specific Call
interface in method signatures. You can use the second one with a WebClient
-backed implementation.
@RetrofitClient("serviceId")
interface HelloClient {
@GET("/")
Call<String> hello();
}
@RetrofitClient("serviceId")
interface HelloClient {
@GET("/")
Mono<String> hello();
}
@RetrofitClient
takes a value
(alias name
) argument, that also indicates the serviceId
that should be used during load-balancing.
If you do not wish for the calls to be load-balanced, you should also use the url
parameter, that allows you to set the full url, with host and port specified explicitly:
@RetrofitClient(name = "localapp", url = "http://localhost:8080")
protected interface TestClient {
@GET("/hello")
Call<Hello> getHello();
}
Apart from setting the URL parameter, the @RetrofitClient
annotation lets you specify a qualifier
and pass a custom configuration
class that you can use to provide or override OkHttp Interceptor
beans:
@RetrofitClient(name = "localapp", configuration = CustomRetrofitConfig.class)
protected interface TestClient {
@GET("/hello")
Call<Hello> getHello();
}
class CustomRetrofitConfig {
@Bean
public Interceptor interceptor1() {
return chain -> {
Request request = chain.request().newBuilder().addHeader(MYHEADER1, "myheader1value").build();
return chain.proceed(request);
};
}
}
The configurations passed by the @RetrofitClient and @EnableRetrofitClients annotations behave similarly to the ones passed via @LoadBalancerClient and @LoadBalancerClients annotations. They are loaded into separate child contexts and should not be annotated with @Configuration .
|
The RetrofitClient bean provided by Spring Cloud Square is set as primary by default. If you wish to provide a different RetrofitClient bean instead, you can change that behaviour by setting the value of spring.cloud.square.retrofit.primary-retrofit-client property to false .
|
3.1. Load-balanced Retrofit Clients
To use Spring Cloud LoadBalancer for instance selection and instance data retrieval, make sure you instantiate either a @LoadBalanced OkHttpClient.Builder
(for a blocking implementation) or a @LoadBalanced Webclient.Builder
(for a reactive implementation) bean in a @Configuration
-annotated class in your application:
@Configuration
@EnableRetrofitClients
class OkHttpClientConfig {
@Bean
@LoadBalanced
public OkHttpClient.Builder okHttpClientBuilder() {
return new OkHttpClient.Builder();
}
}
@Configuration
@EnableRetrofitClients
class OkHttpClientConfig {
@Bean
@LoadBalanced
public WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
}
They are used under the hood to run load-balanced HTTP requests.
You can create various instances of WebClient.Builder with different setup. If a WebClient.Builder bean is found with name matching the pattern [retrofit-context-name]WebClientBuilder , it will be picked for the Retrofit context in question, otherwise the first found WebClient.Builder bean will be picked.
|
3.2. Retrofit Reactor support
When ReactorCallAdapterFactory
is on the classpath (provided by retrofit2-reactor-adapter
dependency), we also instantiate a bean of this type, by using available Scheduler
(if present). You can disable this functionality in properties by setting the value of spring.cloud.square.retrofit.reactor.enabled
to false
.
4. Spring Cloud Sleuth support
We provide tracing support by using Spring Cloud Sleuth integration. If you add spring-cloud-starter-sleuth
to your project setup, tracing is provided either by the WebClient
tracing integration (provided Spring Cloud Sleuth) or by the OkHttpClient
tracing integration (provided by the spring-cloud-square-okhttp module
).
You can disable OkHttp tracing support by setting the value of spring.cloud.square.okhttp.tracing.enabled to false .
|