Skip to content
Permalink
master
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time

Converters

For providing type-safe configuration we need to convert from the configured Strings into target types. This happens by providing Converters in the Config.

Built-in Converters

The following Converters are provided by MicroProfile Config by default:

  • boolean and java.lang.Boolean , values for true (case insensitive) "true", "1", "YES", "Y" "ON". Any other value will be interpreted as false

  • byte and java.lang.Byte

  • short and java.lang.Short

  • int, java.lang.Integer, and java.util.OptionalInt

  • long, java.lang.Long, and java.util.OptionalLong

  • float and java.lang.Float; a dot '.' is used to separate the fractional digits

  • double, java.lang.Double, and java.util.OptionalDouble; a dot '.' is used to separate the fractional digits

  • char and java.lang.Character

  • java.lang.Class based on the result of Class.forName

All built-in Converters have the @Priority of 1.

The converters for these types must throw an NPE if given a null value to convert.

Adding custom Converters

A custom Converter must implement the generic interface org.eclipse.microprofile.config.spi.Converter and conform to the API requirements of that interface. The Type parameter of the interface is the target type the String is converted to. If your converter targets a wrapper of a primitive type (e.g. java.lang.Integer), the converter applies to both the wrapper type and the primitive type (e.g. int) You have to register your implementation in a file /META-INF/services/org.eclipse.microprofile.config.spi.Converter with the fully qualified class name of the custom implementation.

A custom Converter can define a priority with the @jakarta.annotation.Priority annotation. If a Priority annotation isn’t applied, a default priority of 100 is assumed. The Config will use the Converter with the highest Priority for each target type.

A custom Converter for a target type of any of the built-in Converters will overwrite the default Converter.

Converters can be added to the ConfigBuilder programmatically via ConfigBuilder#withConverters(Converter<?>…​ converters) where the type of the converters can be obtained via reflection. However, this is not possible for a lambda converter. In this case, use the method ConfigBuilder#withConverter(Class<T> type, int priority, Converter<T> converter).

Array Converters

For the built-in converters and custom converters, the corresponding Array converters are provided by default. The delimiter for the config value is ",". The escape character is "\". e.g. With this config myPets=dog,cat,dog\,cat, the values as an array will be {"dog", "cat", "dog,cat"}.

Programmatic lookup

Array as a class type is supported in the programmatic lookup.

 String[] myPets = config.getValue("myPets", String[].class);

myPets will be "dog", "cat", "dog,cat" as an array

Injection model

For the property injection, Array, List and Set are supported.

@Inject @ConfigProperty(name="myPets") String[] myPetsArray;
@Inject @ConfigProperty(name="myPets") List<String> myPetsList;
@Inject @ConfigProperty(name="myPets") Set<String> myPetsSet;

myPets will be "dog", "cat", "dog,cat" as an array, List or Set.

Automatic Converters

If no built-in nor custom Converter exists for a requested Type T, an implicit Converter is automatically provided if the following conditions are met:

  • The target type T has a public static T of(String) method, or

  • The target type T has a public static T valueOf(String) method, or

  • The target type T has a public static T parse(CharSequence) method, or

  • The target type T has a public Constructor with a String parameter

If a converter returns null for a given config value, the property will be treated as being deleted. If it is a required property, NoSuchElementException will be thrown. Even if defaultValue is specified on the property injection, the defaultValue will not be used.

Cleaning up a Converter

If a Converter implements the java.lang.AutoCloseable interface then the close() method will be called when the underlying Config is being released.