Spring Cloud for Building Java Microservices: Architecture, Components, and Code Samples
Spring Cloud provides a comprehensive suite of libraries that simplify the development of distributed, cloud-native Java applications by handling cross-cutting concerns like service discovery, load balancing, and fault tolerance.
Spring Cloud extends Spring Boot to address common patterns in distributed systems, allowing developers to focus on business logic rather than infrastructure. The doocs/advanced-java repository offers detailed documentation and minimal code samples demonstrating how to assemble these components into production-ready microservices. This guide synthesizes those resources into a practical implementation reference.
Service Registration and Discovery with Eureka
Eureka acts as the central registry in a Spring Cloud microservices architecture. As documented in docs/micro-services/how-eureka-enable-service-discovery-and-service-registration.md, services register themselves on startup and emit periodic heartbeats to maintain their status in the registry.
Configuring the Eureka Server
To establish a registry, create a Spring Boot application with the @EnableEurekaServer annotation:
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
Add the server dependency to pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
Registering Service Providers
Microservices identify themselves as Eureka clients using @EnableEurekaClient:
@SpringBootApplication
@EnableEurekaClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
A simple REST controller exposes the service functionality:
@RestController
@RequestMapping("/api")
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello from Provider";
}
}
Client-Side Load Balancing
After discovering service instances from Eureka, clients must select one instance to handle the request. The repository's technology stack documentation (docs/micro-services/micro-services-technology-stack.md) identifies Ribbon as the historical solution, though modern Spring Cloud projects use Spring Cloud LoadBalancer as the lightweight, maintained alternative. Both implementations fetch the instance list from Eureka and apply algorithms like round-robin to distribute traffic.
Inter-Service Communication with OpenFeign
Feign eliminates boilerplate HTTP client code by generating type-safe REST clients from Java interfaces. According to the technology stack guide, Feign integrates seamlessly with Ribbon or Spring Cloud LoadBalancer to provide client-side load balancing without explicit configuration.
Enable Feign scanning with @EnableFeignClients:
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = "com.example.consumer.feign")
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
Define the client interface using @FeignClient with the logical service name registered in Eureka:
@FeignClient(name = "provider-service")
public interface HelloClient {
@GetMapping("/api/hello")
String hello();
}
Inject and use the client in a controller:
@RestController
@RequestMapping("/consumer")
@RequiredArgsConstructor
public class ConsumerController {
private final HelloClient helloClient;
@GetMapping("/greet")
public String greet() {
return helloClient.hello();
}
}
Dependency configuration:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Fault Tolerance and Circuit Breaking
To prevent cascading failures, Spring Cloud integrates circuit breaker patterns. The repository documents Hystrix extensively, though notes that since Spring Cloud 2020, it exists in maintenance mode with Sentinel or Resilience4j recommended as successors.
Implement a fallback using Hystrix:
@FeignClient(name = "provider-service", fallback = HelloClientFallback.class)
public interface HelloClient {
@GetMapping("/api/hello")
String hello();
}
@Component
class HelloClientFallback implements HelloClient {
@Override
public String hello() {
return "Fallback response – provider is unavailable";
}
}
The comparison in docs/high-availability/sentinel-vs-hystrix.md details how Sentinel adds adaptive flow control and rate limiting beyond Hystrix's thread-pool isolation model.
Distributed Configuration Management
Spring Cloud Config centralizes configuration files (YAML/Properties) in a Git repository or local filesystem, serving them to all microservices via a dedicated server. The governance documentation (docs/micro-services/micro-service-governance.md) also lists Apollo as an alternative for production-grade configuration management.
Bootstrap a service to fetch external configuration:
spring:
application:
name: provider-service
cloud:
config:
uri: http://config-server:8888
failFast: true
The Config Server itself requires @EnableConfigServer and the following dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
API Gateway with Zuul
Zuul (documented in the technology stack) serves as the single entry point for client requests, handling dynamic routing, authentication, and request transformation. While the repository covers Zuul 1.x via @EnableZuulProxy, modern implementations should consider migrating to Spring Cloud Gateway for non-blocking I/O performance.
Gateway application setup:
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
Security and Observability
The governance document (docs/micro-services/micro-service-governance.md) enumerates Spring Security and OAuth for handling authentication and authorization across service boundaries. For distributed tracing, the technology stack includes Zipkin and Brave to visualize request flows across the microservice ecosystem.
Complete Microservice Lifecycle
According to the architectural documentation in doocs/advanced-java, these components cooperate in a defined lifecycle:
- Bootstrap – Spring Boot applications initialize with
spring-cloud-starterdependencies. - Registration – Services annotate with
@EnableEurekaClientto register with the Eureka registry on startup. - Discovery – Feign clients resolve logical names to physical instances via the load balancer.
- Resilience – Hystrix or Sentinel wraps calls with circuit breaker logic and fallback execution.
- Configuration – Services fetch environment-specific properties from the Config Server at runtime.
- Routing – Zuul or Spring Cloud Gateway applies security filters and routes requests to downstream services.
- Tracing – Zipkin collects span data for end-to-end request visualization.
Summary
- Eureka (
docs/micro-services/how-eureka-enable-service-discovery-and-service-registration.md) provides the service registry using@EnableEurekaServerand@EnableEurekaClient. - Feign simplifies HTTP communication with declarative interfaces annotated with
@FeignClient. - Spring Cloud LoadBalancer replaces Ribbon for client-side load distribution across discovered instances.
- Hystrix and Sentinel (
docs/high-availability/sentinel-vs-hystrix.md) implement circuit breakers to prevent system cascade failures. - Spring Cloud Config centralizes configuration management, supporting dynamic refresh without service restarts.
- Zuul (documented in
docs/micro-services/micro-services-technology-stack.md) acts as the API gateway for routing and cross-cutting concerns.
Frequently Asked Questions
How does Eureka handle service registration and heartbeats?
Eureka clients register on startup by posting metadata to the Eureka Server, then emit periodic heartbeat renewals every 30 seconds (configurable) to maintain their "UP" status. If a client fails to renew within a configured threshold, the server evicts the instance. This lifecycle is detailed in docs/micro-services/how-eureka-enable-service-discovery-and-service-registration.md, which covers the self-preservation mode that prevents mass eviction during network partitions.
What is the difference between Ribbon and Spring Cloud LoadBalancer?
Ribbon was the original client-side load balancer integrated with Eureka and Feign, as noted in docs/micro-services/micro-services-technology-stack.md. However, it entered maintenance mode. Spring Cloud LoadBalancer is the modern, lightweight replacement that ships with Spring Cloud 2020+ releases, providing reactive support and eliminating the need for external Netflix dependencies while maintaining the same round-robin and random selection algorithms.
How does Spring Cloud Config enable dynamic configuration changes?
Services bootstrap with a bootstrap.yml pointing to a Config Server URI (http://config-server:8888). The Config Server (@EnableConfigServer) exposes configuration files stored in a Git repository. While the repository notes support for dynamic refresh, production environments often pair this with Spring Cloud Bus (not explicitly detailed in the source but implied by "dynamic refresh") or Apollo (listed in docs/micro-services/micro-service-governance.md) to push configuration updates to running instances without requiring restarts.
Why would I choose Sentinel over Hystrix for circuit breaking?
As analyzed in docs/high-availability/sentinel-vs-hystrix.md, Sentinel offers flow control, concurrency limiting, and circuit breaking in a single library with a dedicated dashboard, whereas Hystrix focuses primarily on thread isolation and fallbacks. Sentinel supports adaptive traffic shaping and QPS-based limiting, making it more suitable for high-availability scenarios in modern cloud-native deployments where Hystrix's maintenance status makes it a legacy choice.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →