Skip to content

Commit af4508b

Browse files
committed
Document when an property import is relative and when it is fixed
Closes gh-45349
1 parent 5807fa7 commit af4508b

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/features/external-config.adoc

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ If you have already directly xref:features/external-config.adoc#features.externa
274274
[[features.external-config.files.importing]]
275275
=== Importing Additional Data
276276

277-
Application properties may import further config data from other locations using the `spring.config.import` property.
277+
Application properties may import further config data from other locations using the configprop:spring.config.import[] property.
278278
Imports are processed as they are discovered, and are treated as additional documents inserted immediately below the one that declares the import.
279279

280280
For example, you might have the following in your classpath `application.properties` file:
@@ -293,6 +293,46 @@ Values from the imported `dev.properties` will take precedence over the file tha
293293
In the above example, the `dev.properties` could redefine `spring.application.name` to a different value.
294294

295295
An import will only be imported once no matter how many times it is declared.
296+
297+
298+
299+
[[features.external-config.files.importing.fixed-and-relative-paths]]
300+
==== Using "`Fixed`" and "`Import Relative`" Locations
301+
302+
Imports may be specified as _fixed_ or _import relative_ locations.
303+
An fixed location always resolves to the same underlying resource, regardless of the where the configprop:spring.config.import[] property is declared.
304+
An import relative location resolves relative to file that declares the the configprop:spring.config.import[] property.
305+
306+
A location starting with a forward slash (`/`) or a URL style prefix (`file:`, `classpath:`, etc) is considered fixed.
307+
All other locations are considered import relative.
308+
309+
NOTE: `optional:` prefixes are not considered when determining if a location is fixed or import relative.
310+
311+
As an example, say we have a `/demo` directory containing our `application.jar` file.
312+
We might add a `/demo/application.properties` file with the following content:
313+
314+
[,properties]
315+
----
316+
spring.config.import=optional:core/core.properties
317+
----
318+
319+
This is an import relative location and so will attempt to load the file `/demo/core/core.properties` if it exists.
320+
321+
If `/demo/core/core.properties` has the following content:
322+
323+
[,properties]
324+
----
325+
spring.config.import=optional:extra/extra.properties
326+
----
327+
328+
It will attempt to load `/demo/core/extra/extra.properties`.
329+
The `optional:extra/extra.properties` is relative to `/demo/core/core.properties` so the full directory is `/demo/core/` + `extra/extra.properties`.
330+
331+
332+
333+
[[features.external-config.files.importing.import-property-order]]
334+
==== Property Ordering
335+
296336
The order an import is defined inside a single document within the properties/yaml file does not matter.
297337
For instance, the two examples below produce the same result:
298338

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/StandardConfigDataLocationResolver.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ private Set<StandardConfigDataReference> getProfileSpecificReferences(ConfigData
166166
private String getResourceLocation(ConfigDataLocationResolverContext context,
167167
ConfigDataLocation configDataLocation) {
168168
String resourceLocation = configDataLocation.getNonPrefixedValue(PREFIX);
169-
boolean isAbsolute = resourceLocation.startsWith("/") || URL_PREFIX.matcher(resourceLocation).matches();
170-
if (isAbsolute) {
169+
boolean isFixedPath = resourceLocation.startsWith("/") || URL_PREFIX.matcher(resourceLocation).matches();
170+
if (isFixedPath) {
171171
return resourceLocation;
172172
}
173173
ConfigDataResource parent = context.getParent();

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/StandardConfigDataLocationResolverTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ void resolveWhenLocationIsWildcardDirectoriesRestrictsToOneLevelDeep(@ResourcesR
167167
@WithResource(name = "config/1-first/testproperties.properties", content = "first.property=apple")
168168
@WithResource(name = "config/2-second/testproperties.properties", content = "second.property=ball")
169169
@WithResource(name = "config/nested/3-third/testproperties.properties", content = "third.property=shouldnotbefound")
170-
void resolveWhenLocationIsWildcardDirectoriesSortsAlphabeticallyBasedOnAbsolutePath(
170+
void resolveWhenLocationIsWildcardDirectoriesSortsAlphabeticallyBasedOnFixedPath(
171171
@ResourcesRoot Path resourcesRoot) {
172172
ConfigDataLocation location = ConfigDataLocation.of("file:" + resourcesRoot + "/config/*/");
173173
this.environment.setProperty("spring.config.name", "testproperties");

0 commit comments

Comments
 (0)