The following example shows how to use one of the built-in converters (Map to an Object) or create your own.

    1. class MyConfigurationProperties {
    2. public static final String PREFIX = "myapp"
    3. protected LocalDate updatedAt
    4. LocalDate getUpdatedAt() {
    5. return this.updatedAt
    6. }
    7. }
    1. @ConfigurationProperties(MyConfigurationProperties.PREFIX)
    2. class MyConfigurationProperties {
    3. var updatedAt: LocalDate? = null
    4. protected set
    5. companion object {
    6. const val PREFIX = "myapp"
    7. }
    8. }

    The type MyConfigurationProperties features a property called updatedAt which is of type .

    1. @AutoCleanup
    2. @Shared
    3. ApplicationContext ctx = ApplicationContext.run(
    4. "myapp.updatedAt": [day: 28, month: 10, year: 1982] (1)
    5. )
    1. lateinit var ctx: ApplicationContext
    2. @BeforeEach
    3. fun setup() {
    4. ctx = ApplicationContext.run(
    5. mapOf(
    6. "myapp.updatedAt" to mapOf( (1)
    7. "day" to 28,
    8. "year" to 1982
    9. )
    10. )
    11. }
    12. @AfterEach
    13. fun teardown() {
    14. ctx?.close()
    15. }

    This won’t work by default, since there is no built in conversion from Map to LocalDate. To resolve this you can define a custom TypeConverter:

    1. import io.micronaut.core.convert.ConversionContext
    2. import io.micronaut.core.convert.ConversionService
    3. import io.micronaut.core.convert.TypeConverter
    4. import javax.inject.Singleton
    5. import java.time.DateTimeException
    6. import java.time.LocalDate
    7. @Singleton
    8. class MapToLocalDateConverter implements TypeConverter<Map, LocalDate> { (1)
    9. @Override
    10. Optional<LocalDate> convert(Map propertyMap, Class<LocalDate> targetType, ConversionContext context) {
    11. Optional<Integer> day = ConversionService.SHARED.convert(propertyMap.get("day"), Integer.class)
    12. Optional<Integer> month = ConversionService.SHARED.convert(propertyMap.get("month"), Integer.class)
    13. Optional<Integer> year = ConversionService.SHARED.convert(propertyMap.get("year"), Integer.class)
    14. if (day.isPresent() && month.isPresent() && year.isPresent()) {
    15. try {
    16. return Optional.of(LocalDate.of(year.get(), month.get(), day.get())) (2)
    17. } catch (DateTimeException e) {
    18. context.reject(propertyMap, e) (3)
    19. return Optional.empty()
    20. }
    21. return Optional.empty()
    22. }
    23. }
    1. import io.micronaut.core.convert.ConversionContext
    2. import io.micronaut.core.convert.ConversionService
    3. import io.micronaut.core.convert.TypeConverter
    4. import javax.inject.Singleton
    5. import java.time.DateTimeException
    6. import java.time.LocalDate
    7. import java.util.Optional
    8. @Singleton
    9. class MapToLocalDateConverter : TypeConverter<Map<*, *>, LocalDate> { (1)
    10. override fun convert(propertyMap: Map<*, *>, targetType: Class<LocalDate>, context: ConversionContext): Optional<LocalDate> {
    11. val day = ConversionService.SHARED.convert(propertyMap["day"], Int::class.java)
    12. val month = ConversionService.SHARED.convert(propertyMap["month"], Int::class.java)
    13. val year = ConversionService.SHARED.convert(propertyMap["year"], Int::class.java)
    14. if (day.isPresent && month.isPresent && year.isPresent) {
    15. try {
    16. return Optional.of(LocalDate.of(year.get(), month.get(), day.get())) (2)
    17. } catch (e: DateTimeException) {
    18. context.reject(propertyMap, e) (3)
    19. return Optional.empty()
    20. }
    21. }
    22. return Optional.empty()
    23. }
    1The class implements which takes two generic arguments. The type you are converting from and the type you are converting to
    2The implementation delegate to the default shared conversion service to convert the parts of the map that make the day, month and year into a LocalDate
    3If an exception occurs you can call reject(..) which propagates additional information to the container if something goes wrong during binding