Proposed Pull Request Change

title titleSuffix description author ms.author ms.service ms.devlang ms.topic ms.date
Use variant feature flags in a Spring Boot application Azure App Configuration In this tutorial, you learn how to use variant feature flags in a Spring Boot application mrm9084 mametcal azure-app-configuration java tutorial 02/10/2026
📄 Document Links
GitHub View on GitHub Microsoft Learn View on Microsoft Learn
⚠ Content Truncation Detected
The generated rewrite appears to be incomplete.
Original lines: -
Output lines: -
Ratio: -
Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
+0 -0
+0 -0
--- title: 'Use variant feature flags in a Spring Boot application' titleSuffix: Azure App Configuration description: In this tutorial, you learn how to use variant feature flags in a Spring Boot application #customerintent: As a user of Azure App Configuration, I want to learn how I can use variants and variant feature flags in my Spring Boot application. author: mrm9084 ms.author: mametcal ms.service: azure-app-configuration ms.devlang: java ms.topic: tutorial ms.date: 02/10/2026 --- # Tutorial: Use variant feature flags in a Spring Boot application In this tutorial, you use a variant feature flag to manage experiences for different user segments in an example application, *Quote of the Day*. You utilize the variant feature flag created in [Use variant feature flags](./howto-variant-feature-flags.md). Before proceeding, ensure you create the variant feature flag named *Greeting* in your App Configuration store. ## Prerequisites * A supported [Java Development Kit (JDK)](/java/azure/jdk) with version 17 or later. * [Apache Maven](https://maven.apache.org/download.cgi) version 3.0 or later. * Follow the [Use variant feature flags](./howto-variant-feature-flags.md) tutorial and create the variant feature flag named *Greeting*. ## Set up a Spring Boot web app If you already have a Spring Boot web app with authentication, you can skip to the [Use the variant feature flag](#use-the-variant-feature-flag) section. 1. Browse to the [Spring Initializr](https://start.spring.io) and create a new project with the following options: * Generate a **Maven** project with **Java**. * Specify a **Spring Boot** version that's 3.0 or later. * Set the **Group** to `com.example` and **Artifact** to `quoteoftheday`. * Add the **Spring Web**, and **Thymeleaf** dependencies. 1. After you specify the options, select **Generate** to download the project. Extract the files to your local system. ## Create the Quote of the Day app 1. Create a new file named *Quote.java* in the `src/main/java/com/example/quoteoftheday` folder with the following content. It defines a data class for quotes. ```java package com.example.quoteoftheday; public record Quote(String message, String author) { } ``` 1. Create a new file named *HomeController.java* with the following content. It handles the home page display with a random quote. ```java package com.example.quoteoftheday; import java.util.List; import java.util.Random; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @Controller public class HomeController { private final List<Quote> quotes = List.of( new Quote("You cannot change what you are, only what you do.", "Philip Pullman")); private final Random random = new Random(); @GetMapping("/") public String index(Model model) { String greetingMessage = "Hi"; model.addAttribute("greetingMessage", greetingMessage); model.addAttribute("quote", quotes.get(random.nextInt(quotes.size()))); return "index"; } } ``` 1. Create the *templates* directory at `src/main/resources/templates` and add a new file named *index.html* with the following content: ```html <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>QuoteOfTheDay</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"> <link rel="stylesheet" th:href="@{/css/site.css}"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"> </head> <body> <header> <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3"> <div class="container"> <a class="navbar-brand" href="/">QuoteOfTheDay</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> </div> </nav> </header> <div class="container"> <main role="main" class="pb-3"> <div class="quote-container"> <div class="quote-content"> <h3 class="greeting-content" th:if="${greetingMessage}" th:text="${greetingMessage}"></h3> <br /> <p class="quote">"<span th:text="${quote.message}"></span>"</p> <p>- <b th:text="${quote.author}"></b></p> </div> <div class="vote-container"> <button class="btn btn-primary" onclick="heartClicked(this)"> <i class="far fa-heart"></i> </button> </div> </div> </main> </div> <footer class="border-top footer text-muted"> <div class="container"> &copy; 2024 - QuoteOfTheDay </div> </footer> <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script> <script> function heartClicked(button) { var icon = button.querySelector('i'); icon.classList.toggle('far'); icon.classList.toggle('fas'); } </script> </body> </html> ``` 1. Create the *static/css* directory at `src/main/resources/static/css` and add a new file named *site.css* with the following content: ```css html { font-size: 14px; } @media (min-width: 768px) { html { font-size: 16px; } } .btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus { box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb; } html { position: relative; min-height: 100%; } body { margin-bottom: 60px; } body { font-family: Arial, sans-serif; background-color: #f4f4f4; color: #333; } .quote-container { background-color: #fff; margin: 2em auto; padding: 2em; border-radius: 8px; max-width: 750px; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2); display: flex; justify-content: space-between; align-items: start; position: relative; } .vote-container { position: absolute; top: 10px; right: 10px; display: flex; gap: 0em; } .vote-container .btn { background-color: #ffffff; border-color: #ffffff; color: #333 } .vote-container .btn:focus { outline: none; box-shadow: none; } .vote-container .btn:hover { background-color: #F0F0F0; } .greeting-content { font-family: 'Georgia', serif; } .quote-content p.quote { font-size: 2em; font-family: 'Georgia', serif; font-style: italic; color: #4EC2F7; } ``` 1. Update the *application.properties* file at `src/main/resources/application.properties` with the following content: ```properties spring.application.name=quoteoftheday ``` ## Use the variant feature flag 1. Open the *pom.xml* file and add the following dependencies for Azure App Configuration and feature management: ```xml <dependency> <groupId>com.azure.spring</groupId> <artifactId>spring-cloud-azure-starter-appconfiguration-config</artifactId> </dependency> <dependencyManagement> <dependencies> <dependency> <groupId>com.azure.spring</groupId> <artifactId>spring-cloud-azure-dependencies</artifactId> <version>7.0.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ``` 1. Update the *application.properties* file at `src/main/resources/application.properties` to add Azure App Configuration settings: You can connect to your App Configuration store using Microsoft Entra ID (recommended), or a connection string. ### [Microsoft Entra ID (recommended)](#tab/entra-id) ```properties spring.config.import=azureAppConfiguration spring.cloud.azure.appconfiguration.stores[0].endpoint=${APP_CONFIGURATION_ENDPOINT} spring.cloud.azure.appconfiguration.stores[0].feature-flags.enabled=true ``` You use the `DefaultAzureCredential` to authenticate to your App Configuration store. Follow the [instructions](./concept-enable-rbac.md#authentication-with-token-credentials) to assign your credential the **App Configuration Data Reader** role. Be sure to allow sufficient time for the permission to propagate before running your application. ### [Connection string](#tab/connection-string) ```properties spring.config.import=azureAppConfiguration spring.cloud.azure.appconfiguration.stores[0].connection-string=${APP_CONFIGURATION_CONNECTION_STRING} spring.cloud.azure.appconfiguration.stores[0].feature-flags.enabled=true ``` --- 1. Create a new file named *QueryStringTargetingContextAccessor.java* to provide the targeting context for the current user: ```java package com.example.quoteoftheday; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.azure.spring.cloud.feature.management.targeting.TargetingContext; import com.azure.spring.cloud.feature.management.targeting.TargetingContextAccessor; @Component public class QueryStringTargetingContextAccessor implements TargetingContextAccessor { @Override public void configureTargetingContext(TargetingContext context) { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder .getRequestAttributes(); if (attributes != null) { String userId = attributes.getRequest().getParameter("userId"); if (userId != null) { context.setUserId(userId); } } } } ``` 1. Update *HomeController.java* to use the variant feature flag: ```java package com.example.quoteoftheday; import java.util.List; import java.util.Random; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import com.azure.spring.cloud.feature.management.FeatureManager; import com.azure.spring.cloud.feature.management.models.Variant; @Controller public class HomeController { private static final Logger LOGGER = LoggerFactory.getLogger(HomeController.class); private final FeatureManager featureManager; private final List<Quote> quotes = List.of( new Quote("You cannot change what you are, only what you do.", "Philip Pullman")); private final Random random = new Random(); public HomeController(FeatureManager featureManager) { this.featureManager = featureManager; } @GetMapping("/") public String index(Model model) { // Get the variant for the Greeting feature flag String greetingMessage = ""; Variant variant = featureManager.getVariant("Greeting"); if (variant != null) { Object value = variant.getValue(); if (value != null) { greetingMessage = value.toString(); } } else { LOGGER.warn( "No variant given. Either the feature flag named 'Greeting' is not defined or the variants are not defined properly."); } model.addAttribute("greetingMessage", greetingMessage); model.addAttribute("quote", quotes.get(random.nextInt(quotes.size()))); return "index"; } } ``` ## Build and run the app 1. Set an environment variable. ### [Microsoft Entra ID (recommended)](#tab/entra-id) Set the environment variable named **APP_CONFIGURATION_ENDPOINT** to the endpoint of your App Configuration store found under the *Overview* of your store in the Azure portal. If you use the Windows command prompt, run the following command and restart the command prompt to allow the change to take effect: ```cmd setx APP_CONFIGURATION_ENDPOINT "<AppConfigurationEndpoint>" ``` If you use PowerShell, run the following command: ```powershell $Env:APP_CONFIGURATION_ENDPOINT = "<AppConfigurationEndpoint>" ``` If you use macOS or Linux, run the following command: ```bash export APP_CONFIGURATION_ENDPOINT='<AppConfigurationEndpoint>' ``` ### [Connection string](#tab/connection-string) Set the environment variable named **APP_CONFIGURATION_CONNECTION_STRING** to the read-only connection string of your App Configuration store found under *Access settings* of your store in the Azure portal. If you use the Windows command prompt, run the following command and restart the command prompt to allow the change to take effect: ```cmd setx APP_CONFIGURATION_CONNECTION_STRING "<AppConfigurationConnectionString>" ``` If you use PowerShell, run the following command: ```powershell $Env:APP_CONFIGURATION_CONNECTION_STRING = "<AppConfigurationConnectionString>" ``` If you use macOS or Linux, run the following command: ```bash export APP_CONFIGURATION_CONNECTION_STRING='<AppConfigurationConnectionString>' ``` --- 1. Build and run your Spring Boot application with Maven: ```shell mvn clean package mvn spring-boot:run ``` 1. Wait for the app to start, and then open a browser and navigate to `http://localhost:8080/`. You should see the default view of the app that doesn't have any greeting message. :::image type="content" source="media/how-to-variant-feature-flags-spring-boot/default-variant.png" alt-text="Screenshot of the Quote of the day app, showing no greeting message for the user."::: 1. You can use `userId` query parameter in the url to specify the user ID. Visit `localhost:8080/?userId=UserA` and you see a long greeting message. :::image type="content" source="media/how-to-variant-feature-flags-spring-boot/long-variant.png" alt-text="Screenshot of the Quote of the day app, showing long greeting message for the user."::: 1. Try different user IDs to see how the variant feature flag changes the greeting message for different segments of users. Visit `localhost:8080/?userId=UserB` and you see a shorter greeting message. :::image type="content" source="media/how-to-variant-feature-flags-spring-boot/simple-variant.png" alt-text="Screenshot of the Quote of the day app, showing simple greeting message for the user."::: ## Next steps For the full feature rundown of the Spring Boot feature management library, refer to the following document. > [!div class="nextstepaction"] > [Use feature flags in a Spring Boot app](./use-feature-flags-spring-boot.md)
Success! Branch created successfully. Create Pull Request on GitHub
Error: