diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfiguration.java index cbf9f303c2..d3a16cdb54 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfiguration.java @@ -76,8 +76,9 @@ public class MessageSourceAutoConfiguration { } messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale()); Duration cacheDuration = properties.getCacheDuration(); - messageSource.setCacheSeconds( - cacheDuration == null ? -1 : (int) cacheDuration.getSeconds()); + if (cacheDuration != null) { + messageSource.setCacheMillis(cacheDuration.toMillis()); + } messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat()); messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage()); return messageSource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceProperties.java index 1935b10f7b..62d366c2cd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceProperties.java @@ -19,6 +19,9 @@ package org.springframework.boot.autoconfigure.context; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.time.Duration; +import java.time.temporal.ChronoUnit; + +import org.springframework.boot.convert.DurationUnit; /** * Configuration properties for Message Source. @@ -44,8 +47,9 @@ public class MessageSourceProperties { /** * Loaded resource bundle files cache duration. When not set, bundles are cached - * forever. + * forever. If a duration suffix is not specified, seconds will be used. */ + @DurationUnit(ChronoUnit.SECONDS) private Duration cacheDuration; /** diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java index 3098a73865..810e765de3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java @@ -23,7 +23,9 @@ import org.junit.Test; import org.springframework.beans.DirectFieldAccessor; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.ContextConsumer; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceResolvable; import org.springframework.context.NoSuchMessageException; @@ -82,6 +84,30 @@ public class MessageSourceAutoConfigurationTests { .isEqualTo("Some text with some swedish öäå!")); } + @Test + public void testCacheDurationNoUnit() { + this.contextRunner + .withPropertyValues("spring.messages.basename:test/messages", + "spring.messages.cache-duration=10") + .run(assertCache(10 * 1000)); + } + + @Test + public void testCacheDurationWithUnit() { + this.contextRunner + .withPropertyValues("spring.messages.basename:test/messages", + "spring.messages.cache-duration=1m") + .run(assertCache(60 * 1000)); + } + + private ContextConsumer assertCache(long expected) { + return (context) -> { + assertThat(assertThat(context).hasSingleBean(MessageSource.class)); + assertThat(new DirectFieldAccessor(context.getBean(MessageSource.class)) + .getPropertyValue("cacheMillis")).isEqualTo(expected); + }; + } + @Test public void testMultipleMessageSourceCreated() { this.contextRunner diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 4639839df8..8b71c419a0 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -123,7 +123,7 @@ content into your application. Rather, pick only the properties that you need. # INTERNATIONALIZATION ({sc-spring-boot-autoconfigure}/context/MessageSourceProperties.{sc-ext}[MessageSourceProperties]) spring.messages.always-use-message-format=false # Whether to always apply the MessageFormat rules, parsing even messages without arguments. spring.messages.basename=messages # Comma-separated list of basenames (essentially a fully-qualified classpath location), each following the ResourceBundle convention with relaxed support for slash based locations. - spring.messages.cache-duration=-1 # Loaded resource bundle files cache duration. When not set, bundles are cached forever. + spring.messages.cache-duration= # Loaded resource bundle files cache duration. When not set, bundles are cached forever. If a duration suffix is not specified, seconds will be used. spring.messages.encoding=UTF-8 # Message bundles encoding. spring.messages.fallback-to-system-locale=true # Whether to fall back to the system Locale if no files for a specific Locale have been found. spring.messages.use-code-as-default-message=false # Whether to use the message code as the default message instead of throwing a "NoSuchMessageException". Recommended during development only.