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 845cb133e7..cbf9f303c2 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -118,9 +118,10 @@ public class MessageSourceAutoConfiguration { } private Resource[] getResources(ClassLoader classLoader, String name) { + String target = name.replace('.', '/'); try { return new PathMatchingResourcePatternResolver(classLoader) - .getResources("classpath*:" + name + ".properties"); + .getResources("classpath*:" + target + ".properties"); } catch (Exception ex) { return NO_RESOURCES; 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 b11773fee4..17b5dce46a 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 @@ -30,9 +30,10 @@ import java.time.Duration; public class MessageSourceProperties { /** - * Comma-separated list of basenames, each following the ResourceBundle convention. - * Essentially a fully-qualified classpath location. If it doesn't contain a package - * qualifier (such as "org.mypackage"), it will be resolved from the classpath root. + * Comma-separated list of basenames (essentially a fully-qualified classpath + * location), each following the ResourceBundle convention with relaxed support for + * slash based locations. If it doesn't contain a package qualifier (such as + * "org.mypackage"), it will be resolved from the classpath root. */ private String basename = "messages"; 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 8d12cd92d1..9a2cbe6c79 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 @@ -55,11 +55,24 @@ public class MessageSourceAutoConfigurationTests { } @Test - public void testMessageSourceCreated() { + public void propertiesBundleWithSlashIsDetected() { this.contextRunner.withPropertyValues("spring.messages.basename:test/messages") - .run((context) -> assertThat( - context.getMessage("foo", null, "Foo message", Locale.UK)) - .isEqualTo("bar")); + .run((context) -> { + assertThat(context).hasSingleBean(MessageSource.class); assertThat( + context.getMessage("foo", null, "Foo message", Locale.UK)) + .isEqualTo("bar"); + }); + } + + @Test + public void propertiesBundleWithDotIsDetected() { + this.contextRunner.withPropertyValues("spring.messages.basename:test.messages") + .run((context) -> { + assertThat(context).hasSingleBean(MessageSource.class); + assertThat( + context.getMessage("foo", null, "Foo message", Locale.UK)) + .isEqualTo("bar"); + }); } @Test 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 87a0a09b09..37a89f17c4 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 @@ -121,7 +121,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, each following the ResourceBundle convention. + 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.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.