Skip to content

Instantly share code, notes, and snippets.

@aoudiamoncef
Last active May 31, 2024 07:49
Show Gist options
  • Save aoudiamoncef/5e0562d3f4a25965eccbddb2b573f91d to your computer and use it in GitHub Desktop.
Save aoudiamoncef/5e0562d3f4a25965eccbddb2b573f91d to your computer and use it in GitHub Desktop.
Spring Boot Custom Configuration Properties With Java Records + Validations + Metadata

Spring Boot Custom Configuration Properties With Java Records + Validations + Metadata

This project demonstrates how to use Java records with Spring Boot to define custom configuration properties. These properties include validations and metadata annotations to enhance IDE support and ensure data integrity.

Java Records

Java records, introduced in Java 14, provide a concise and readable way to define immutable data objects. In this project, we utilize Java records to define our custom configuration properties. Each record represents a set of related configuration properties with predefined fields.

Validations

Validation constraints from the jakarta.validation.constraints package are applied to the fields of the Java records. These constraints ensure that the configuration properties meet certain criteria, such as being not blank or positive. By enforcing validations, we can prevent invalid configurations and maintain data integrity within our application.

Metadata

In addition of Javadoc, metadata annotations such as @DefaultValue are used to provide default values for configuration properties and enhance IDE support. These annotations improve the developer experience by providing additional context and information about the properties directly in the code.

Usage

  1. Define your custom configuration properties using Java records in the specified package.
  2. Apply validation constraints to the fields of the records to ensure data integrity.
  3. Use metadata annotations to provide default values and enhance IDE support.
  4. Integrate the custom configuration properties into your Spring Boot application by specifying the prefix and binding them from the application.yml or application.properties file.
  5. Import configuration properties classes explicility or by package scanning in the application main method.

Example

app:
  buffer-max-size: 500
  bulk-size: 100
  collection-name: address
  enriching-key: product
  enriching-uri: http://localhost:1519/products/1

Dependencies

  • Spring Boot
  • Jakarta Validation API

References

package com.maoudia;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableConfigurationProperties(AppProperties.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
app:
buffer-max-size: 500
bulk-size: 100
collection-name: address
enriching-key: product
enriching-uri: http://localhost:1519/products/1
package com.maoudia;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.DefaultValue;
import org.springframework.validation.annotation.Validated;
import java.net.URI;
/**
* Configuration properties for the application.
* These properties are bound from the application.yml (or application.properties) file using the specified prefix.
*/
@ConfigurationProperties(prefix = "app")
@Validated
public record AppProperties(
/*
* The bulk size configuration.
*/
@DefaultValue("128")
@Positive
int bulkSize,
/*
* The maximum buffer size configuration.
*/
@DefaultValue("1024")
@Positive
int bufferMaxSize,
/*
* The name of the collection.
*/
@NotBlank
String collectionName,
/*
* The key used for enriching.
*/
@NotBlank
String enrichingKey,
/*
* The URI used for enriching.
*/
@NotNull
URI enrichingUri
) {
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.maoudia.app</groupId>
<artifactId>app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>maoudia-app</name>
<description>MAOUDIA APP</description>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
{
"groups": [
{
"name": "app",
"type": "com.maoudia.AppProperties",
"sourceType": "com.maoudia.AppProperties"
}
],
"properties": [
{
"name": "app.buffer-max-size",
"type": "java.lang.Integer",
"sourceType": "com.maoudia.AppProperties",
"defaultValue": 1024
},
{
"name": "app.bulk-size",
"type": "java.lang.Integer",
"sourceType": "com.maoudia.AppProperties",
"defaultValue": 128
},
{
"name": "app.collection-name",
"type": "java.lang.String",
"sourceType": "com.maoudia.AppProperties"
},
{
"name": "app.enriching-key",
"type": "java.lang.String",
"sourceType": "com.maoudia.AppProperties"
},
{
"name": "app.enriching-uri",
"type": "java.net.URI",
"sourceType": "com.maoudia.AppProperties"
}
],
"hints": []
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment