Spring BootSpring Cloud
Spring Boot

Spring Cloud

Spring Cloud is an umbrella project that provides production-ready building blocks for microservices on the JVM. It integrates with Spring Boot to deliver service discovery (Eureka), API gateway (Spring Cloud Gateway), client-side load balancing (Spring Cloud LoadBalancer), distributed configuration (Spring Cloud Config), circuit breaking (Resilience4j), and distributed tracing (Micrometer Tracing / Zipkin).

Spring Cloud Overview and BOM

Spring Cloud is not a single library β€” it is a collection of sub-projects versioned together under a release train (e.g. 2023.0.x for Spring Boot 3.x). The Bill of Materials (BOM) pins compatible versions of all sub-projects so you never have to manage individual library versions. Import the BOM once in pom.xml and then declare individual starters without version tags.
XML
<!-- pom.xml β€” import Spring Cloud BOM: -->
<properties>
    <java.version>21</java.version>
    <spring-cloud.version>2023.0.3</spring-cloud.version>
</properties>

<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>

<!-- Individual starters β€” no <version> needed: -->
<dependencies>

    <!-- Service discovery client (registers with Eureka): -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <!-- API Gateway: -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>

    <!-- Centralised configuration: -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>

    <!-- Circuit breaker (Resilience4j integration): -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
    </dependency>

    <!-- OpenFeign declarative HTTP client: -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

</dependencies>

// ── Spring Boot ↔ Spring Cloud version compatibility: ────────────────
// Spring Boot 3.2.x / 3.3.x β†’ Spring Cloud 2023.0.x (Leyton)
// Spring Boot 3.0.x / 3.1.x β†’ Spring Cloud 2022.0.x (Kilburn)
// Spring Boot 2.7.x          β†’ Spring Cloud 2021.0.x (Jubilee)
// Always verify at: https://spring.io/projects/spring-cloud

Key Spring Cloud Components

Spring Cloud composes several focused sub-projects. Each solves a distinct microservices concern. You include only the starters you need β€” there is no requirement to use all components together.
Java
// ── Spring Cloud component map ────────────────────────────────────────
//
//  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
//  β”‚                     CLIENT / BROWSER                            β”‚
//  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
//                              β”‚
//                              β–Ό
//  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
//  β”‚  Spring Cloud Gateway  (API Gateway)                            β”‚
//  β”‚  β€’ Route requests to downstream services                        β”‚
//  β”‚  β€’ Auth filters, rate limiting, SSL termination                 β”‚
//  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
//             β”‚                     β”‚
//             β–Ό                     β–Ό
//  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
//  β”‚  User Service    β”‚   β”‚  Order Service   β”‚   ...more services
//  β”‚  @DiscoveryClientβ”‚   β”‚  @DiscoveryClientβ”‚
//  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
//           β”‚                      β”‚
//           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
//                      β”‚  register / lookup
//                      β–Ό
//  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
//  β”‚  Spring Cloud Netflix Eureka (Registry) β”‚
//  β”‚  β€’ Tracks all live service instances    β”‚
//  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
//
//  Supporting components (used inside each service):
//
//  Spring Cloud Config      β†’ externalise application.yml to a Git repo
//  Spring Cloud LoadBalancer→ client-side load balancing across instances
//  Spring Cloud OpenFeign   β†’ declarative REST client (@FeignClient)
//  Resilience4j             β†’ circuit breaker, retry, rate limiter
//  Micrometer Tracing       β†’ distributed tracing (exports to Zipkin/Tempo)

// ── Component responsibilities at a glance: ───────────────────────────
// Gateway         β†’ WHERE do requests go?
// Eureka          β†’ WHERE is each service running right now?
// Config Server   β†’ WHAT configuration does each service use?
// LoadBalancer    β†’ WHICH instance handles this request?
// OpenFeign       β†’ HOW does service A call service B?
// Resilience4j    β†’ WHAT happens when service B is down?
// Micrometer      β†’ HOW do we trace a request across services?

Spring Cloud Config Server

Spring Cloud Config Server externalises configuration for all microservices into a central Git repository. Each service fetches its configuration on startup (and optionally at runtime via /actuator/refresh). This eliminates per-service application.yml files scattered across repos and enables environment-specific config (dev, staging, prod) without rebuilding images.
Java
// ── Config Server setup: ─────────────────────────────────────────────

// pom.xml (config-server module only):
// <dependency>
//   <groupId>org.springframework.cloud</groupId>
//   <artifactId>spring-cloud-config-server</artifactId>
// </dependency>

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}

// application.yml (Config Server):
// server:
//   port: 8888
// spring:
//   cloud:
//     config:
//       server:
//         git:
//           uri: https://github.com/your-org/microservices-config
//           default-label: main
//           search-paths: '{application}'   # look in a folder per service

// ── Git repo structure (microservices-config): ───────────────────────
// microservices-config/
// β”œβ”€β”€ application.yml          ← shared defaults for ALL services
// β”œβ”€β”€ user-service/
// β”‚   β”œβ”€β”€ application.yml      ← user-service defaults
// β”‚   β”œβ”€β”€ application-dev.yml  ← user-service dev overrides
// β”‚   └── application-prod.yml ← user-service prod overrides
// └── order-service/
//     β”œβ”€β”€ application.yml
//     └── application-prod.yml

// ── Config Client (every microservice): ──────────────────────────────

// pom.xml:
// <dependency>
//   <groupId>org.springframework.cloud</groupId>
//   <artifactId>spring-cloud-starter-config</artifactId>
// </dependency>

// bootstrap.yml (loaded before application.yml):
// spring:
//   application:
//     name: user-service          # determines which file is fetched
//   config:
//     import: "configserver:http://localhost:8888"
//   profiles:
//     active: dev                 # fetches user-service/application-dev.yml

// ── Config Server REST API (built-in): ───────────────────────────────
// GET /{application}/{profile}[/{label}]
//
// http://localhost:8888/user-service/dev
// http://localhost:8888/user-service/prod/main
// Returns merged config: application.yml + user-service.yml + profile override

OpenFeign Declarative HTTP Client

Spring Cloud OpenFeign lets you call another microservice by writing an interface annotated with @FeignClient β€” no RestTemplate or WebClient boilerplate. Feign integrates automatically with Eureka (resolves service names) and Spring Cloud LoadBalancer (client-side load balancing), and can wrap calls with Resilience4j circuit breakers.
Java
// pom.xml:
// <dependency>
//   <groupId>org.springframework.cloud</groupId>
//   <artifactId>spring-cloud-starter-openfeign</artifactId>
// </dependency>

// ── Enable Feign on the main application class: ───────────────────────
@SpringBootApplication
@EnableFeignClients
public class OrderServiceApplication { ... }

// ── Declare the Feign client interface: ───────────────────────────────
// 'name' matches spring.application.name of the target service.
// Eureka resolves the name to a real host:port at runtime.
@FeignClient(
    name = "user-service",
    fallback = UserClientFallback.class   // optional circuit breaker fallback
)
public interface UserClient {

    @GetMapping("/api/users/{id}")
    UserResponse findById(@PathVariable Long id);

    @PostMapping("/api/users")
    UserResponse create(@RequestBody CreateUserRequest request);

    @GetMapping("/api/users")
    List<UserResponse> findAll(
        @RequestParam(required = false) String role
    );
}

// ── Fallback (used when UserService is down): ─────────────────────────
@Component
public class UserClientFallback implements UserClient {

    @Override
    public UserResponse findById(Long id) {
        return UserResponse.builder().id(id).name("Unknown").build();
    }

    @Override
    public UserResponse create(CreateUserRequest request) {
        throw new ServiceUnavailableException("user-service is down");
    }

    @Override
    public List<UserResponse> findAll(String role) {
        return Collections.emptyList();
    }
}

// ── Inject and use in a service: ─────────────────────────────────────
@Service
@RequiredArgsConstructor
public class OrderService {

    private final UserClient userClient;  // Feign proxy injected by Spring

    public OrderResponse placeOrder(CreateOrderRequest req) {
        UserResponse user = userClient.findById(req.getUserId());
        // Feign handles: HTTP call, serialisation, load balancing, retries.
        Order order = orderRepository.save(Order.from(req, user));
        return OrderResponse.from(order);
    }
}

// ── application.yml β€” enable Feign + Resilience4j fallbacks: ─────────
// spring:
//   cloud:
//     openfeign:
//       circuitbreaker:
//         enabled: true