<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Eduardo</title>
    <description>The latest articles on Forem by Eduardo (@eduesqui).</description>
    <link>https://forem.com/eduesqui</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F748253%2F20de9331-de28-4842-a4fe-714a0d605d3b.png</url>
      <title>Forem: Eduardo</title>
      <link>https://forem.com/eduesqui</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/eduesqui"/>
    <language>en</language>
    <item>
      <title>Minimal Guide to Resilience4j and Circuit Breaker in Spring Boot</title>
      <dc:creator>Eduardo</dc:creator>
      <pubDate>Tue, 30 Dec 2025 18:25:14 +0000</pubDate>
      <link>https://forem.com/eduesqui/minimal-guide-to-resilience4j-and-circuit-breaker-in-spring-boot-25lj</link>
      <guid>https://forem.com/eduesqui/minimal-guide-to-resilience4j-and-circuit-breaker-in-spring-boot-25lj</guid>
      <description>&lt;p&gt;Resilience4j is a library designed to guarantee application availability, mainly in high-load environments. With the rise of Microservices, it has become essential to control what happens when one of our services fails or is slow to respond, preventing a "cascading failure."&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Circuit Breaker?
&lt;/h2&gt;

&lt;p&gt;The Circuit Breaker pattern works similarly to electrical breakers in a house. If it detects a failure, it "opens" the circuit to prevent further damage and "closes" it once the problem is resolved.&lt;/p&gt;

&lt;p&gt;A Circuit Breaker has three main states:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Closed: Everything is working correctly. Requests flow normally.&lt;/li&gt;
&lt;li&gt;Open: Failures have exceeded the allowed threshold. Requests are blocked and a fallback is executed.&lt;/li&gt;
&lt;li&gt;Half-Open: A trial period where a limited number of requests are allowed to check if the service has recovered.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Resilience4j Configuration
&lt;/h2&gt;

&lt;p&gt;To start, we create a Spring Boot project and add the following dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
   &amp;lt;groupId&amp;gt;io.github.resilience4j&amp;lt;/groupId&amp;gt;
   &amp;lt;artifactId&amp;gt;resilience4j-spring-boot2&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our application.yml, we define the parameters that will govern the behavior of our Circuit Breaker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resilience4j:
  circuitbreaker:
    instances:
      mainService:
        registerHealthIndicator: true
        slidingWindowSize: 10
        permittedNumberOfCallsInHalfOpenState: 3
        slidingWindowType: COUNT_BASED
        minimumNumberOfCalls: 5
        waitDurationInOpenState: 10s
        failureRateThreshold: 50
        eventConsumerBufferSize: 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parameter Breakdown:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;slidingWindowSize: The number of calls to record when the circuit is closed.&lt;/li&gt;
&lt;li&gt;failureRateThreshold: The percentage of failures (e.g., 50%) at which the circuit should open.&lt;/li&gt;
&lt;li&gt;waitDurationInOpenState: How long the circuit stays "Open" before trying to recover.&lt;/li&gt;
&lt;li&gt;permittedNumberOfCallsInHalfOpenState: Number of successful calls needed in "Half-Open" to close the circuit again
.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Implementation with Annotations
&lt;/h2&gt;

&lt;p&gt;The easiest way to use it is by using the @CircuitBreaker annotation. We must specify the name of the instance we configured in the YAML and a fallback method.&lt;/p&gt;

&lt;p&gt;Note: The fallback method must have the same signature as the original method, but it must also receive a Throwable or Exception as an argument.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Implementation with Annotations
&lt;/h2&gt;

&lt;p&gt;The easiest way to use it is by using the @CircuitBreaker annotation. We must specify the name of the instance we configured in the YAML and a fallback method.&lt;/p&gt;

&lt;p&gt;Note: The fallback method must have the same signature as the original method, but it must also receive a Throwable or Exception as an argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
public class ProductService {

    @CircuitBreaker(name = "mainService", fallbackMethod = "fallbackGetProducts")
    public List&amp;lt;Product&amp;gt; getProducts() {
        // Logic that might fail (e.g., calling an external API)
        return externalApi.fetchProducts();
    }

    // Fallback Method
    public List&amp;lt;Product&amp;gt; fallbackGetProducts(Throwable e) {
        return List.of(new Product("Default Product", 0.0));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Other Resilience4j Modules
&lt;/h2&gt;

&lt;p&gt;While the Circuit Breaker is the most famous, Resilience4j offers other tools to improve stability:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TimeLimiter&lt;/strong&gt;&lt;br&gt;
Used to set a maximum execution time for a request. If the service doesn't respond within the timeframe, it triggers a failure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retry&lt;/strong&gt;&lt;br&gt;
Allows us to automatically retry a failed operation a specific number of times before giving up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bulkhead&lt;/strong&gt;&lt;br&gt;
Limits the number of concurrent calls to a service to avoid saturating resources (like thread pools).&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Resilience4j is a powerful tool for building robust Microservices. By implementing the Circuit Breaker pattern, we ensure that our application can fail gracefully instead of crashing completely under pressure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://funcionaenmimaquina.com/guia-minima-de-resilience4j-y-circuit-breaker-en-spring-boot/" rel="noopener noreferrer"&gt;Post in spanish&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Spring Cloud Gateway: Basic Example</title>
      <dc:creator>Eduardo</dc:creator>
      <pubDate>Tue, 30 Dec 2025 18:03:07 +0000</pubDate>
      <link>https://forem.com/eduesqui/spring-cloud-gateway-basic-example-5dhm</link>
      <guid>https://forem.com/eduesqui/spring-cloud-gateway-basic-example-5dhm</guid>
      <description>&lt;p&gt;Spring Cloud Gateway (also known as a gateway or Edge Service) is a dynamic routing server. In other words, it allows us to have a centralized access point to our Microservices. Additionally, we can extend its functionality by adding filters or predicates, among other things.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Spring Cloud Gateway Configuration
&lt;/h2&gt;

&lt;p&gt;We create a project using Spring Initializr or our favorite IDE, making sure to select the following dependencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eureka Discovery Client &lt;/li&gt;
&lt;li&gt;Gateway&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project will also be registered by Eureka Server, so we add the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@EnableEurekaClient
@SpringBootApplication
public class EurekaClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaClientApplication.class, args);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we configure the application name and the port where it will be deployed. We can do this in a properties or yml file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring:
  application:
    name: gateway-server-service
server:
  port: 8090
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like the previous configuration, Spring Cloud Gateway can be configured in a properties file or a yml file, but for easier reading, I will show the yml configuration here.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Routes
&lt;/h2&gt;

&lt;p&gt;The minimum essential configuration for the Edge or Gateway is the routes. These routes will redirect requests from the Gateway to the service that will answer the request.&lt;/p&gt;

&lt;p&gt;The following is an example of a basic route configuration in YAML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring:
  cloud:
    gateway:
      routes:
        - id: employees
          uri: lb://employees
          predicates:
            - Path=/api/employees/**
          filters:
            - StripPrefix=2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;id: Unique identifier of the route.&lt;/li&gt;
&lt;li&gt;uri: Address where the Edge will look for the service to redirect. It must start with lb (Load Balancer) if using service discovery like Eureka.&lt;/li&gt;
&lt;li&gt;predicates: Series of rules that must be met for the redirection.&lt;/li&gt;
&lt;li&gt;filters: Help us work with the request and response passing through the declared route.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the case of the example, it is routing to a Microservice called employees (or empleados), and if we want to get a response from it, we can use the Spring Cloud Gateway pointing to the Edge port and not to the Microservice Port directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 Predicates
&lt;/h3&gt;

&lt;p&gt;Predicates are a list of rules that must be met for the redirection to the service to be successful.&lt;/p&gt;

&lt;p&gt;Predicates can be of various types: by redirection address, by header, by method type, query, or cookie.&lt;/p&gt;

&lt;p&gt;List of possible examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;predicates:
  - Path=/api/products/**
  - Header=token, \d+
  - Method=GET, POST
  - Query=color
  - Cookie=color, blue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meaning of the predicates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Path: Allows redirection of requests that match the declared path.&lt;/li&gt;
&lt;li&gt;Header: Checks that the declared header comes within the request with the indicated value (regex capable).&lt;/li&gt;
&lt;li&gt;Method: Indicates that it only receives the declared HTTP methods.&lt;/li&gt;
&lt;li&gt;Query: Indicates that the search parameter must appear in the URL query.&lt;/li&gt;
&lt;li&gt;Cookie: Checks that the indicated cookie is present.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.2 Spring Cloud Gateway Factory Filters
&lt;/h3&gt;

&lt;p&gt;There are filters that help us manipulate the request and response. This means you can add information to the request or response within the headers or as a parameter in the request.&lt;/p&gt;

&lt;p&gt;The way to add it is in the application.yml file within the configuration section of the desired path in a comma-separated key-value format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;filters:
  - AddRequestHeader=token-request, 123456
  - AddResponseHeader=token-response, 12345678
  - SetResponseHeader=Content-Type, text/plain
  - AddRequestParameter=name, andres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3 Spring Cloud Gateway Global Filters
&lt;/h3&gt;

&lt;p&gt;There is a way to make a filter pass through all our requests and responses without having to declare it one by one. In the following example, we are going to add a header to the request and a cookie to the response of all requests that pass through the Spring Cloud Gateway.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.funcionaenmimaquina.springboot.app.gateway.filters;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Optional;

@Component
public class ExampleGlobalFilter implements GlobalFilter, Ordered {

    private final Logger logger = LoggerFactory.getLogger(ExampleGlobalFilter.class);

    @Override
    public Mono&amp;lt;Void&amp;gt; filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        logger.info("Executing request filter");

        // Modifying the request
        exchange.getRequest().mutate().headers(h -&amp;gt; h.add("environment", "dev"));

        return chain.filter(exchange).then(Mono.fromRunnable(() -&amp;gt; {
            logger.info("Executing response filter");

            // Modifying the response
            Optional.ofNullable(exchange.getRequest().getHeaders().getFirst("environment")).ifPresent(value -&amp;gt; {
                exchange.getResponse().getHeaders().add("env", value);
            });

            exchange.getResponse().getHeaders().setContentType(MediaType.TEXT_PLAIN);
        }));
    }

    @Override
    public int getOrder() {
        return 1;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To understand the previous example, we must highlight several things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It implements the GlobalFilter and Ordered interfaces.&lt;/li&gt;
&lt;li&gt;The overridden method getOrder is used to give an order in case of having more global filter classes.&lt;/li&gt;
&lt;li&gt;In the overridden filter method, all the logic to interact with our request and response is written.&lt;/li&gt;
&lt;li&gt;Line 24 shows the section where you can manipulate the request, in this case adding a header.&lt;/li&gt;
&lt;li&gt;Line 27 shows how to manipulate a response (using .then(Mono.fromRunnable(...))).&lt;/li&gt;
&lt;li&gt;Line 31 adds a header to the response if the condition that a specific header exists is met.&lt;/li&gt;
&lt;li&gt;Line 34 manipulates the response to take a plain text format.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2.4 Filter Factory (Custom Gateway Filter)
&lt;/h3&gt;

&lt;p&gt;If we do not want the Filter to pass through all requests and responses, but only through those we specify, we can create a custom filter as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component
public class ExampleGatewayFilterFactory extends AbstractGatewayFilterFactory&amp;lt;ExampleGatewayFilterFactory.Config&amp;gt; {

    private final Logger logger = LoggerFactory.getLogger(ExampleGatewayFilterFactory.class);

    public ExampleGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -&amp;gt; {
            logger.info("Zone to modify the request");

            return chain.filter(exchange).then(Mono.fromRunnable(() -&amp;gt; {
                logger.info("Zone to modify the response");

                Optional.ofNullable(config.cookieValue).ifPresent(cookieVal -&amp;gt; {
                    exchange.getResponse().addCookie(ResponseCookie.from(config.cookieName, cookieVal).build());
                });
            }));
        };
    }

    @Override
    public String name() {
        return "ExampleCookie";
    }

    @Override
    public List&amp;lt;String&amp;gt; shortcutFieldOrder() {
        return Arrays.asList("cookieName", "cookieValue");
    }

    public static class Config {
        private String cookieName;
        private String cookieValue;

        // Getters and Setters
        public String getCookieValue() { return cookieValue; }
        public void setCookieValue(String cookieValue) { this.cookieValue = cookieValue; }
        public String getCookieName() { return cookieName; }
        public void setCookieName(String cookieName) { this.cookieName = cookieName; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage in YML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;filters:
  - StripPrefix=2
  - ExampleCookie=user, myName
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What the code above does is add a Cookie to the response of the request with the values described in the yml file, and the following should be highlighted:&lt;/p&gt;

&lt;p&gt;By convention, the class name must end in FilterFactory.&lt;/p&gt;

&lt;p&gt;It extends the AbstractGatewayFilterFactory class.&lt;/p&gt;

&lt;p&gt;You need to use a configuration class (inner class Config); this configuration class will store the values sent from the yml file.&lt;/p&gt;

&lt;p&gt;The functionality is coded inside the apply method.&lt;/p&gt;

&lt;p&gt;The return value of the name() method must match the key in the yml file (or default to the class name prefix).&lt;/p&gt;

&lt;p&gt;The shortcutFieldOrder method indicates the order in which the values will be assigned from the YAML short notation.&lt;/p&gt;

&lt;p&gt;Now this filter will only be applied to the requests configured within the application.yml file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Now you know what Spring Cloud Gateway is for and what you can achieve by configuring it. You know how to configure predicates and filters to extend its functionality. Don't forget to practice to be able to use it in the professional world.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://funcionaenmimaquina.com/spring-cloud-gateway-ejemplo-basico/" rel="noopener noreferrer"&gt;Post in spanish&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>springcloud</category>
    </item>
    <item>
      <title>How to Configure Eureka Server</title>
      <dc:creator>Eduardo</dc:creator>
      <pubDate>Tue, 30 Dec 2025 17:30:04 +0000</pubDate>
      <link>https://forem.com/eduesqui/how-to-configure-eureka-server-3om4</link>
      <guid>https://forem.com/eduesqui/how-to-configure-eureka-server-3om4</guid>
      <description>&lt;p&gt;The goal of Eureka Server is to locate and register services you want to interact with. Additionally, it helps with load balancing and fault tolerance.&lt;/p&gt;

&lt;p&gt;To configure Eureka Server, there must be at least two types of applications: one application acting as the server and another as the client.&lt;/p&gt;

&lt;p&gt;Each service must communicate with the Eureka Server to tell it that it is available for use. Eureka Server will store its information and status. This communication between the microservice and Eureka is called heartbeats and occurs every 30 seconds. If 3 heartbeats fail, Eureka Server removes it from the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Configure the Eureka Server Project
&lt;/h2&gt;

&lt;p&gt;To create the project, we can use the Spring Boot Initializr tool or the wizard in your preferred IDE. For this example, Spring Boot version 2.7.0 will be used.&lt;/p&gt;

&lt;p&gt;During project creation, we must ensure we select "Eureka Server"  (usually listed as Eureka Server in Initializr) so that our project has the necessary libraries to perform the example.&lt;/p&gt;

&lt;p&gt;Once the project is created, we must configure our properties file (application.yml) as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eureka:
  client:
    fetch-registry: false
    register-with-eureka: false
spring:
  application:
    name: servicio-eureka-server
server:
  port: 8761
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The configuration inside the eureka node prevents the Eureka Server application from registering itself. The spring node gives the name to the application we are working on, and the server node indicates the port on which the application will run. By convention, Eureka Server is assigned this port number (8761).&lt;/p&gt;

&lt;p&gt;Finally, we must add the &lt;code&gt;@EnableEurekaServer&lt;/code&gt; annotation to our class containing the main method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@EnableEurekaServer
@SpringBootApplication
public class SpringBootEurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootEurekaServerApplication.class, args);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test the application, we run it and go to &lt;a href="http://localhost:8761" rel="noopener noreferrer"&gt;http://localhost:8761&lt;/a&gt;, where we can observe the Eureka Server dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw409wp7icave83saymw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw409wp7icave83saymw9.png" alt="Eureka Server" width="800" height="817"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Configuration of a Eureka Client
&lt;/h2&gt;

&lt;p&gt;To create the application that will connect to Eureka Server, we follow a similar process to the previous one using Spring Boot Initializr or our preferred IDE. However, now we must ensure we select "Eureka Discovery Client" so that it can be correctly registered in Eureka Server.&lt;/p&gt;

&lt;p&gt;Now we configure the application.yml of the Eureka Client as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring:
  application:
    name: eureka-client
server:
  port: ${PORT:0}
eureka:
  instance:
    instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we saw earlier, the spring.application.name node gives the application its name. server.port indicates the communication port where the application will start; in this case, we are not setting a specific port but leaving it dynamic (${PORT:0}).&lt;/p&gt;

&lt;p&gt;Now, the instance-id node is necessary to be able to run on a different random port with a different random instance ID. In this case, instance-id is formed by the application name and a random value.&lt;/p&gt;

&lt;p&gt;Now we must declare in the main method that this is a Eureka Client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@EnableEurekaClient
@SpringBootApplication
public class EurekaClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaClientApplication.class, args);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To verify that Eureka Server registers the services correctly, we first start Eureka Server, and then we can start the Eureka Client application twice to verify that the ports do not clash and that the port number and instance ID are random.&lt;/p&gt;

&lt;p&gt;Now we go to &lt;a href="http://localhost:8761" rel="noopener noreferrer"&gt;http://localhost:8761&lt;/a&gt; to verify this. We can notice that the ports did not clash, they each have a different random ID, and they are correctly registered in Eureka Server.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. How to Consume a Eureka Client Service
&lt;/h2&gt;

&lt;p&gt;Now we are going to build a service that makes a request to our service called Eureka Client. To do this, we are going to modify our Eureka Client service slightly by adding a Rest Controller, and we will create a new service that functions as a Rest client.&lt;/p&gt;

&lt;p&gt;Rest Controller in Eureka Client&lt;br&gt;
Inside the Eureka Client Project, we are first going to create a POJO Object that will be returned to be visualized as a result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Item implements Serializable {
    private static final long serialVersionUID = 129348938L;
    private int i;
    private String name;

    public Item() {
    }

    public Item(int i, String name) {
        this.i = i;
        this.name = name;
    }

    // Getters, Setters, Equals and HashCode
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // ... equals and hashCode methods
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we create some dummy business logic where we obtain a list of Item objects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public interface ItemService {
    List&amp;lt;Item&amp;gt; findAll();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
public class ItemServiceImpl implements ItemService {
    @Override
    public List&amp;lt;Item&amp;gt; findAll() {
        List&amp;lt;Item&amp;gt; items = new ArrayList&amp;lt;&amp;gt;();
        Item item;
        for(int i = 0 ; i &amp;lt; 10; i++){
            item = new Item(i, "Item " + i);
            items.add(item);
        }
        return items;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we link it with the controller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestController
public class ItemController {

    private static Logger logger = LoggerFactory.getLogger(ItemController.class);

    @Autowired
    private ItemService itemService;

    @GetMapping(path = "/listing", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity&amp;lt;List&amp;lt;Item&amp;gt;&amp;gt; listing(){
        List&amp;lt;Item&amp;gt; all = itemService.findAll();
        return new ResponseEntity&amp;lt;&amp;gt;(all, HttpStatus.OK);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Spring Boot Feign Client
&lt;/h2&gt;

&lt;p&gt;Now we are going to create a new project that will serve as a client for our Microservice using Feign.&lt;/p&gt;

&lt;p&gt;First, we create an object representing Item in this project as well (similar to the code above).&lt;/p&gt;

&lt;p&gt;Now we create the Feign client. In the name property, we put the name of the service exactly as we registered it in Eureka Server.&lt;/p&gt;

&lt;p&gt;You might notice that no URL or port is configured within this connection. This is thanks to Eureka and the fact that we configured a random port in the Eureka Client. Now we can spin up N number of services with random ports and everything will work transparently.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@FeignClient(name = "eureka-client")
public interface ProductRestClient {

    @GetMapping(path = "/listing")
    public List&amp;lt;ItemDto&amp;gt; list();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public interface ItemService {
    public List&amp;lt;ItemDto&amp;gt; findAll();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
public class ItemServiceFeign implements ItemService {

    @Autowired
    private ProductRestClient feignClient; // Feign Client

    @Override
    public List&amp;lt;ItemDto&amp;gt; findAll() {
        return feignClient.list();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create the Controller for the Feign client and configure the project properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestController
public class ItemController {

    @Autowired
    private ItemService itemService;

    @GetMapping(path = "/list")
    public List&amp;lt;ItemDto&amp;gt; list(){
        return itemService.findAll();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring:
  application:
    name: feign-client
server:
  port: 8002
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our example is now ready to be tested. Using any browser, we can go to the URL &lt;a href="http://localhost:8002/list" rel="noopener noreferrer"&gt;http://localhost:8002/list&lt;/a&gt; and we will get the JSON result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;In this post, we were able to see how Eureka helps us scale our services, and makes communication between them easier. We created an example to observe how it behaves and how simple it is to configure Eureka Server. Now we can use it for our projects or to create our portfolio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Relevant Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://funcionaenmimaquina.com/como-configurar-eureka-server/" rel="noopener noreferrer"&gt;Post in spanish
&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>java</category>
      <category>springboot</category>
      <category>eureka</category>
    </item>
    <item>
      <title>Builder Pattern in Java: Clear Examples and Real Application</title>
      <dc:creator>Eduardo</dc:creator>
      <pubDate>Tue, 30 Dec 2025 17:02:49 +0000</pubDate>
      <link>https://forem.com/eduesqui/builder-pattern-in-java-clear-examples-and-real-application-2jmj</link>
      <guid>https://forem.com/eduesqui/builder-pattern-in-java-clear-examples-and-real-application-2jmj</guid>
      <description>&lt;p&gt;The Builder design pattern in Java is a creational design pattern. It allows you to separate the construction of an object from its representation. In other words, it enables the creation of an object step-by-step. This is especially useful for complex objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you use the Builder pattern?
&lt;/h2&gt;

&lt;p&gt;Imagine we have an object with 8 attributes. To create it, we need to write a constructor with 8 arguments. But what if we don't want to use all 8 attributes? Since passing null as a parameter is a bad practice, should we create a constructor for 7 arguments, and one for each possible combination of parameters?&lt;/p&gt;

&lt;p&gt;For these cases, we can apply the Builder design pattern in Java.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the advantages of using the Builder pattern?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Flexibility&lt;/strong&gt;: It allows the creation of objects with the desired number of parameters in a natural way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Readability&lt;/strong&gt;: The implementation of this pattern is easy to follow and understand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Immutability&lt;/strong&gt;: It is possible to enforce immutability once the object has finished being built, thus guaranteeing thread safety against unwanted modifications.&lt;/p&gt;

&lt;h2&gt;
  
  
  How is the Builder pattern implemented in Java?
&lt;/h2&gt;

&lt;p&gt;Since design patterns are abstract solutions to recurring problems, we can adapt our implementations according to the context we are in. For this reason, here are several examples of how to implement the Builder design pattern in Java.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Classic Builder Design Pattern in Java
&lt;/h3&gt;

&lt;p&gt;This is the classic way to create the Builder design pattern in Java.&lt;/p&gt;

&lt;p&gt;The first thing to notice is the private final attributes of our object, the getter methods, and the omission of setter methods. This makes the values immutable.&lt;/p&gt;

&lt;p&gt;Next, we see the static Builder class which repeats the same fields as the main Product class, and each attribute has a method to set information. We can see the constructor that only receives the builder object. Finally, we see the build method that returns an object of type Product.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.funcionaenmimaquina.builder.classic;

public class Product {
    private final String name;
    private final String description;
    private final double price;
    private final String category;
    private final String imageUrl;
    private final String brand;
    private final String sku;

    private Product(Builder builder) {
        this.name = builder.name;
        this.description = builder.description;
        this.price = builder.price;
        this.category = builder.category;
        this.imageUrl = builder.imageUrl;
        this.brand = builder.brand;
        this.sku = builder.sku;
    }

    public static class Builder {
        private String name;
        private String description;
        private double price;
        private String category;
        private String imageUrl;
        private String brand;
        private String sku;

        public Builder name(String name) {
            this.name = name;
            return this;
        }

        public Builder description(String description) {
            this.description = description;
            return this;
        }

        public Builder price(double price) {
            this.price = price;
            return this;
        }

        public Builder category(String category) {
            this.category = category;
            return this;
        }

        public Builder imageUrl(String imageUrl) {
            this.imageUrl = imageUrl;
            return this;
        }

        public Builder brand(String brand) {
            this.brand = brand;
            return this;
        }

        public Builder sku(String sku) {
            this.sku = sku;
            return this;
        }

        public Product build() {
            return new Product(this);
        }
    }

    @Override
    public String toString() {
        return "Product{" +
                "name='" + name + '\'' +
                ", description='" + description + '\'' +
                ", price=" + price +
                ", category='" + category + '\'' +
                ", imageUrl='" + imageUrl + '\'' +
                ", brand='" + brand + '\'' +
                ", sku='" + sku + '\'' +
                '}';
    }

    // Getters...
    public String getName() { return name; }
    public String getDescription() { return description; }
    public double getPrice() { return price; }
    public String getCategory() { return category; }
    public String getImageUrl() { return imageUrl; }
    public String getBrand() { return brand; }
    public String getSku() { return sku; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can use the Java builder in the following way. We create an object of type Product.Builder, which allows us to access the methods for assigning attribute values, and finally, we call the build method to finish constructing our object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static void runClassicBuilder() {
    System.out.println("Classic Builder Pattern Example");
    Product product = new Product.Builder()
            .name("Laptop")
            .description("High performance laptop")
            .price(1200.00)
            .category("Electronics")
            .imageUrl("http://example.com/laptop.jpg")
            .brand("BrandX")
            .sku("SKU12345")
            .build();
    System.out.println(product.toString());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Generic Builder Design Pattern with Lambdas
&lt;/h3&gt;

&lt;p&gt;Thanks to lambdas, we can create a generic builder to use with all our objects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.function.BiConsumer;
import java.util.function.Supplier;

public class Builder&amp;lt;T&amp;gt; {
    private final Supplier&amp;lt;T&amp;gt; supplier;

    private Builder(Supplier&amp;lt;T&amp;gt; supplier) {
        this.supplier = supplier;
    }

    public static &amp;lt;T&amp;gt; Builder&amp;lt;T&amp;gt; of(Supplier&amp;lt;T&amp;gt; supplier) {
        return new Builder&amp;lt;&amp;gt;(supplier);
    }

    public &amp;lt;P&amp;gt; Builder&amp;lt;T&amp;gt; with(BiConsumer&amp;lt;T, P&amp;gt; consumer, P value) {
        return new Builder&amp;lt;&amp;gt;(() -&amp;gt; {
            T object = supplier.get();
            consumer.accept(object, value);
            return object;
        });
    }

    public T build() {
        return supplier.get();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's use a User class for this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class User {
    private String name;
    private String lastname;
    private String secondLastName;
    private String phone;
    private String email;

    // Getters and Setters needed
    public void setName(String name) { this.name = name; }
    public void setLastname(String lastname) { this.lastname = lastname; }
    public void setSecondLastName(String secondLastName) { this.secondLastName = secondLastName; }
    public void setPhone(String phone) { this.phone = phone; }
    public void setEmail(String email) { this.email = email; }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", lastname='" + lastname + '\'' +
                ", secondLastName='" + secondLastName + '\'' +
                ", phone='" + phone + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generic builder uses the of() method to assign the data type and the with() method to assign the value to the object's attribute. The usage of this builder looks elegant and friendly to read. It provides flexibility, but since it relies on the object's setters, it leaves immutability aside.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static void runGenericBuilder() {
    System.out.println("Generic Builder Pattern Example");
    User user = Builder.of(User::new)
            .with(User::setName, "John")
            .with(User::setLastname, "Doeh")
            .with(User::setSecondLastName, "Doeh")
            .with(User::setPhone, "555555")
            .with(User::setEmail, "mail@mail.com")
            .build();
    System.out.println(user.toString());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Builder Design Pattern in Java with Lombok
&lt;/h3&gt;

&lt;p&gt;Lombok is a Java library that helps us eliminate boilerplate code through annotations. Among its many functions, it gives us a way to implement the Builder design pattern simply.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import lombok.Builder;
import lombok.Getter;
import lombok.ToString;

@Builder
@Getter
@ToString
public class Videogame {
    private String name;
    private String platform;
    private String category;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static void runLombokBuilder() {
    System.out.println("Lombok Builder Pattern Example");
    Videogame videogame = Videogame.builder()
            .name("The Legend of Zelda")
            .platform("Nintendo Switch")
            .category("Action-Adventure")
            .build();
    System.out.println(videogame.toString());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also use the &lt;a class="mentioned-user" href="https://dev.to/builder"&gt;@builder&lt;/a&gt; annotation on Records.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Builder
public record SoccerTeam(String name, String country, String coach) {
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Builder Design Pattern using Records in Java
&lt;/h3&gt;

&lt;p&gt;Records arrived in Java with the mission of creating immutable classes without boilerplate code. If we want to use the Builder design pattern in Java with Records (without Lombok), we can do it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public record Smartphone(String model, String brand, String operatingSystem, double price) {

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {
        private String model;
        private String brand;
        private String operatingSystem;
        private double price;

        public Builder model(String model) {
            this.model = model;
            return this;
        }

        public Builder brand(String brand) {
            this.brand = brand;
            return this;
        }

        public Builder operatingSystem(String operatingSystem) {
            this.operatingSystem = operatingSystem;
            return this;
        }

        public Builder price(double price) {
            this.price = price;
            return this;
        }

        public Smartphone build() {
            return new Smartphone(model, brand, operatingSystem, price);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we can observe the build method inside the Builder class that creates the object, and the static builder() method in the Record that returns the Builder object so we can access the value assignment methods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static void runRecordBuilder() {
    System.out.println("Record Builder Pattern Example");
    Smartphone smartphone = Smartphone.builder()
            .model("iPhone 14")
            .brand("Apple")
            .operatingSystem("iOS")
            .price(999.99)
            .build();
    System.out.println(smartphone.toString());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Now we know what the Builder design pattern is for and we have seen that there are several ways to implement it. It is important to know the context of our project to know which one best adapts to our needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Relevant Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://funcionaenmimaquina.com/como-implementar-el-patron-de-diseno-builder-en-java/" rel="noopener noreferrer"&gt;Post in Spanish&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/eduesqui/builder" rel="noopener noreferrer"&gt;Code on github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>designpatterns</category>
    </item>
    <item>
      <title>@ConditionalOnProperty In Spring Boot</title>
      <dc:creator>Eduardo</dc:creator>
      <pubDate>Tue, 03 Jun 2025 16:06:39 +0000</pubDate>
      <link>https://forem.com/eduesqui/conditionalonproperty-in-spring-boot-pfd</link>
      <guid>https://forem.com/eduesqui/conditionalonproperty-in-spring-boot-pfd</guid>
      <description>&lt;p&gt;Sometimes we need to create different types of beans depending on certain conditions. Let's suppose we have a system in which we send notifications, and some clients of that system prefer notifications via email, while others prefer SMS notifications. In this case, we would need to inject a different bean for each client. To solve this problem, we can use the @ConditionalOnProperty annotation in Spring Boot.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is @ConditionalOnProperty In Spring Boot?
&lt;/h2&gt;

&lt;p&gt;@ConditionalOnProperty can read Spring Boot properties and, based on their values, determine whether the Bean will be created or not. This can be useful for solving the problem presented in the previous paragraph, or, for example, if we want to use a different Bean for the dev and prod environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does @ConditionalOnProperty work in Spring Boot?
&lt;/h2&gt;

&lt;p&gt;The operation of the annotation is quite intuitive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ConditionalOnProperty(name = "someName", havingValue = "true")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the “name” attribute we put the property on whose value the creation of the Bean will depend and the “havingValue” attribute determines the expected value to create the Bean or not.&lt;/p&gt;

&lt;p&gt;Example of using @ConditionalOnProperty in Spring Boot&lt;/p&gt;

&lt;p&gt;The first thing we need to do is create a property in the application yml file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;configuration:
  smsMessageEnabled: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can create an Interface and two classes that inherit from this interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
@ConditionalOnProperty(name = "configuration.emailMessageEnabled", havingValue = "true")
public class EmailMessageServiceImpl implements MessageService{

    private static final Logger log = LoggerFactory.getLogger(EmailMessageServiceImpl.class);

    @Override
    public void sendMessage(String message) {
       log.info("Sending Email message: {}",message);
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public interface MessageService {
    void sendMessage(String message);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
@ConditionalOnProperty(name = "configuration.smsMessageEnabled", havingValue = "true")
public class SmsMessageServiceImpl implements MessageService{

    private static final Logger log = LoggerFactory.getLogger(SmsMessageServiceImpl.class);

    @Override
    public void sendMessage(String message) {
        log.info("Sending SMS message: {}",message);
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the previous code we can see how we implemented the sendMessage method only with a log just for the purposes of the @ConditionalOnProperty example; in a real case this could be a call to some API.&lt;/p&gt;

&lt;p&gt;In the @ConditionalOnProperty annotation we can see the reference to the property name that we wrote in the application yml file.&lt;/p&gt;

&lt;p&gt;Now we have to test the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@SpringBootApplication
public class ConditionalOnProperty {

  private static final Logger logger = LoggerFactory.getLogger(ConditionalOnProperty.class);

  @Autowired
  MessageService messageService;

  public static void main(String[] args) {
    SpringApplication.run(ConditionalOnProperty.class, args);

  }

  @EventListener(ApplicationReadyEvent.class)
  public void onApplicationReady() {
    logger.info("Start");
    messageService.sendMessage("Any Text ");
    logger.info("Finish");
  }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will get an output like this:&lt;/p&gt;

&lt;p&gt;We can see that we got the call of the method of the SmsMessageServiceImpl class which was the one we configured in the application.yml file&lt;/p&gt;

&lt;h2&gt;
  
  
  What did we learn?
&lt;/h2&gt;

&lt;p&gt;Now we know that @ConditionalOnProperty helps us create beans based on defined conditions. Using it allows us to adapt our code to different environments, giving us greater flexibility in our application's behavior.&lt;/p&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>spring</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
