Check for existence of ResourceBundle before creating MessageSource

Irritatingly a ResourceBundleMessageSource never gives up trying to
create a resource bundle for every message resolution, so to stop
it logging all those warnings (and probably sucking performance-wise)
we need to disable the MessageSource if a bundle is not provided.

Fixes gh-1019
pull/1031/head
Dave Syer 11 years ago
parent 1567964e14
commit 0def7644c2

@ -16,16 +16,25 @@
package org.springframework.boot.autoconfigure; package org.springframework.boot.autoconfigure;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration.ResourceBundleCondition;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.context.EnvironmentAware; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean; 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.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import static org.springframework.util.StringUtils.commaDelimitedListToStringArray; import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
@ -39,28 +48,77 @@ import static org.springframework.util.StringUtils.trimAllWhitespace;
@Configuration @Configuration
@ConditionalOnMissingBean(MessageSource.class) @ConditionalOnMissingBean(MessageSource.class)
@Order(Ordered.HIGHEST_PRECEDENCE) @Order(Ordered.HIGHEST_PRECEDENCE)
public class MessageSourceAutoConfiguration implements EnvironmentAware { @Conditional(ResourceBundleCondition.class)
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "spring.messages")
public class MessageSourceAutoConfiguration {
private RelaxedPropertyResolver environment; private String basename = "messages";
@Override private String encoding = "utf-8";
public void setEnvironment(Environment environment) {
this.environment = new RelaxedPropertyResolver(environment, "spring.messages."); private int cacheSeconds = -1;
}
@Bean @Bean
public MessageSource messageSource() { public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
String basename = this.environment.getProperty("basename", "messages"); if (StringUtils.hasText(this.basename)) {
if (StringUtils.hasText(basename)) {
messageSource messageSource
.setBasenames(commaDelimitedListToStringArray(trimAllWhitespace(basename))); .setBasenames(commaDelimitedListToStringArray(trimAllWhitespace(this.basename)));
} }
String encoding = this.environment.getProperty("encoding", "utf-8"); messageSource.setDefaultEncoding(this.encoding);
messageSource.setDefaultEncoding(encoding); messageSource.setCacheSeconds(this.cacheSeconds);
messageSource.setCacheSeconds(this.environment.getProperty("cacheSeconds",
Integer.class, -1));
return messageSource; return messageSource;
} }
public String getBasename() {
return this.basename;
}
public void setBasename(String basename) {
this.basename = basename;
}
public String getEncoding() {
return this.encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public int getCacheSeconds() {
return this.cacheSeconds;
}
public void setCacheSeconds(int cacheSeconds) {
this.cacheSeconds = cacheSeconds;
}
protected static class ResourceBundleCondition extends SpringBootCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
String basename = context.getEnvironment().getProperty(
"spring.messages.basename", "messages");
if (!StringUtils.hasText(basename)) {
return ConditionOutcome.noMatch("Empty spring.messages.basename");
}
for (String name : commaDelimitedListToStringArray(trimAllWhitespace(basename))) {
try {
ResourceBundle.getBundle(name, Locale.getDefault(),
context.getClassLoader());
}
catch (MissingResourceException e) {
return ConditionOutcome
.noMatch("Bundle found for spring.messages.basename: " + name);
}
}
return ConditionOutcome.match("Bundle found for spring.messages.basename: "
+ basename);
}
}
} }

@ -46,10 +46,10 @@ public class MessageSourceAutoConfigurationTests {
@Test @Test
public void testMessageSourceCreated() throws Exception { public void testMessageSourceCreated() throws Exception {
this.context = new AnnotationConfigApplicationContext(); this.context = new AnnotationConfigApplicationContext();
this.context.register(MessageSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
EnvironmentTestUtils.addEnvironment(this.context, EnvironmentTestUtils.addEnvironment(this.context,
"spring.messages.basename:test/messages"); "spring.messages.basename:test/messages");
this.context.register(MessageSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh(); this.context.refresh();
assertEquals("bar", assertEquals("bar",
this.context.getMessage("foo", null, "Foo message", Locale.UK)); this.context.getMessage("foo", null, "Foo message", Locale.UK));
@ -58,10 +58,10 @@ public class MessageSourceAutoConfigurationTests {
@Test @Test
public void testMultipleMessageSourceCreated() throws Exception { public void testMultipleMessageSourceCreated() throws Exception {
this.context = new AnnotationConfigApplicationContext(); this.context = new AnnotationConfigApplicationContext();
this.context.register(MessageSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
EnvironmentTestUtils.addEnvironment(this.context, EnvironmentTestUtils.addEnvironment(this.context,
"spring.messages.basename:test/messages,test/messages2"); "spring.messages.basename:test/messages,test/messages2");
this.context.register(MessageSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh(); this.context.refresh();
assertEquals("bar", assertEquals("bar",
this.context.getMessage("foo", null, "Foo message", Locale.UK)); this.context.getMessage("foo", null, "Foo message", Locale.UK));
@ -72,10 +72,10 @@ public class MessageSourceAutoConfigurationTests {
@Test @Test
public void testBadEncoding() throws Exception { public void testBadEncoding() throws Exception {
this.context = new AnnotationConfigApplicationContext(); this.context = new AnnotationConfigApplicationContext();
this.context.register(MessageSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
EnvironmentTestUtils.addEnvironment(this.context, EnvironmentTestUtils.addEnvironment(this.context,
"spring.messages.encoding:rubbish"); "spring.messages.encoding:rubbish");
this.context.register(MessageSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh(); this.context.refresh();
// Bad encoding just means the messages are ignored // Bad encoding just means the messages are ignored
assertEquals("blah", this.context.getMessage("foo", null, "blah", Locale.UK)); assertEquals("blah", this.context.getMessage("foo", null, "blah", Locale.UK));

Loading…
Cancel
Save