From fb7f858a8e9c2e2a6805138146eafd195f81d494 Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Thu, 23 May 2024 09:48:05 +0800 Subject: [PATCH] Allow resolving nested placeholders if value is not String but CharSequence See https://github.com/spring-projects/spring-boot/issues/34195 --- .../env/PropertySourcesPropertyResolver.java | 7 ++-- .../PropertySourcesPropertyResolverTests.java | 38 +++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/env/PropertySourcesPropertyResolver.java b/spring-core/src/main/java/org/springframework/core/env/PropertySourcesPropertyResolver.java index b97fad87484f..c008e8088ced 100644 --- a/spring-core/src/main/java/org/springframework/core/env/PropertySourcesPropertyResolver.java +++ b/spring-core/src/main/java/org/springframework/core/env/PropertySourcesPropertyResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 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. @@ -24,6 +24,7 @@ * * @author Chris Beams * @author Juergen Hoeller + * @author Yanming Zhou * @since 3.1 * @see PropertySource * @see PropertySources @@ -84,8 +85,8 @@ protected T getProperty(String key, Class targetValueType, boolean resolv } Object value = propertySource.getProperty(key); if (value != null) { - if (resolveNestedPlaceholders && value instanceof String string) { - value = resolveNestedPlaceholders(string); + if (resolveNestedPlaceholders && value instanceof CharSequence cs) { + value = resolveNestedPlaceholders(cs.toString()); } logKeyFound(key, propertySource, value); return convertValueIfNecessary(value, targetValueType); diff --git a/spring-core/src/test/java/org/springframework/core/env/PropertySourcesPropertyResolverTests.java b/spring-core/src/test/java/org/springframework/core/env/PropertySourcesPropertyResolverTests.java index d442f6a0cb7d..dcaa4dd6d92c 100644 --- a/spring-core/src/test/java/org/springframework/core/env/PropertySourcesPropertyResolverTests.java +++ b/spring-core/src/test/java/org/springframework/core/env/PropertySourcesPropertyResolverTests.java @@ -34,6 +34,7 @@ /** * @author Chris Beams + * @author Yanming Zhou * @since 3.1 */ class PropertySourcesPropertyResolverTests { @@ -300,6 +301,43 @@ void resolveNestedPropertyPlaceholders() { .withMessageContaining("Circular"); } + @Test + void resolveNestedPlaceholdersIfValueIsCharSequence() { + MutablePropertySources ps = new MutablePropertySources(); + ps.addFirst(new MockPropertySource() + .withProperty("p1", "v1") + .withProperty("p2", "v2") + .withProperty("p3", new CharSequence() { + + static final String underlying = "${p1}:${p2}"; + + @Override + public int length() { + return underlying.length(); + } + + @Override + public char charAt(int index) { + return underlying.charAt(index); + } + + @Override + public CharSequence subSequence(int start, int end) { + return underlying.subSequence(start, end); + } + + @Override + public String toString() { + return underlying; + } + }) + ); + ConfigurablePropertyResolver pr = new PropertySourcesPropertyResolver(ps); + assertThat(pr.getProperty("p1")).isEqualTo("v1"); + assertThat(pr.getProperty("p2")).isEqualTo("v2"); + assertThat(pr.getProperty("p3")).isEqualTo("v1:v2"); + } + @Test void ignoreUnresolvableNestedPlaceholdersIsConfigurable() { MutablePropertySources ps = new MutablePropertySources();