Commit 22abe35f authored by Rui Figueira's avatar Rui Figueira Committed by Phillip Webb

Add ReloadableResourceBundleMessageSource support

Add a `spring.messages.reloadable` configuration property which can be
used to auto-configure a `ReloadableResourceBundleMessageSource` rather
than a `ResourceBundleMessageSource`.

Closes gh-13377
parent 8b595032
......@@ -33,6 +33,8 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.AbstractResourceBasedMessageSource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.core.Ordered;
import org.springframework.core.io.Resource;
......@@ -65,7 +67,9 @@ public class MessageSourceAutoConfiguration {
@Bean
public MessageSource messageSource(MessageSourceProperties properties) {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
AbstractResourceBasedMessageSource messageSource = (properties.isReloadable()
? new ReloadableResourceBundleMessageSource()
: new ResourceBundleMessageSource());
if (StringUtils.hasText(properties.getBasename())) {
messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(
StringUtils.trimAllWhitespace(properties.getBasename())));
......
......@@ -71,6 +71,12 @@ public class MessageSourceProperties {
*/
private boolean useCodeAsDefaultMessage = false;
/**
* Whether to use a "ReloadableResourceBundleMessageSource" rather than the default
* "ResourceBundleMessageSource". Recommended during development only.
*/
private boolean reloadable = false;
public String getBasename() {
return this.basename;
}
......@@ -119,4 +125,12 @@ public class MessageSourceProperties {
this.useCodeAsDefaultMessage = useCodeAsDefaultMessage;
}
public boolean isReloadable() {
return this.reloadable;
}
public void setReloadable(boolean reloadable) {
this.reloadable = reloadable;
}
}
......@@ -21,6 +21,7 @@ import java.util.Locale;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
......@@ -32,6 +33,9 @@ import org.springframework.context.NoSuchMessageException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.DelegatingMessageSource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.context.support.ResourceBundleMessageSource;
import static org.assertj.core.api.Assertions.assertThat;
......@@ -220,6 +224,43 @@ public class MessageSourceAutoConfigurationTests {
.isEqualTo("bar")));
}
@Test
public void testDefaultReloadableValueMessageSource() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
.run((context) -> assertThat(getDeclaredMessageSource(context))
.isInstanceOf(ResourceBundleMessageSource.class));
}
@Test
public void testNotReloadableMessageSource() {
this.contextRunner
.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.reloadable:false")
.run((context) -> assertThat(getDeclaredMessageSource(context))
.isInstanceOf(ResourceBundleMessageSource.class));
}
@Test
public void testReloadableMessageSource() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.reloadable:true").run((context) -> {
assertThat(getDeclaredMessageSource(context))
.isInstanceOf(ReloadableResourceBundleMessageSource.class);
assertThat(context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("bar");
});
}
private MessageSource getDeclaredMessageSource(AssertableApplicationContext context)
throws BeansException {
MessageSource messageSource = context.getBean(MessageSource.class);
if (messageSource instanceof DelegatingMessageSource) {
messageSource = ((DelegatingMessageSource) messageSource)
.getParentMessageSource();
}
return messageSource;
}
@Configuration
@PropertySource("classpath:/switch-messages.properties")
protected static class Config {
......
......@@ -133,6 +133,7 @@ content into your application. Rather, pick only the properties that you need.
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.reloadable=false # Whether to use a ReloadableResourceBundleMessageSource instead of the default ResourceBundleMessageSource. Recommended during development only.
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.
# OUTPUT
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment