mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Add internal property replacement
E.g. in application.properties (for launcher) foo: Application loader.main: my.${foo} loader.path: etc
This commit is contained in:
parent
a70d293c87
commit
a3af83cf96
@ -25,6 +25,7 @@ import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Logger;
|
||||
@ -69,14 +70,30 @@ public class PropertiesLauncher implements ArchiveFilter {
|
||||
public static final String MAIN = "loader.main";
|
||||
|
||||
/**
|
||||
* Properties key for classpath entries (directories possibly containing jars)
|
||||
* Properties key for classpath entries (directories possibly containing jars).
|
||||
* Defaults to "lib/" (relative to {@link #HOME loader home directory}).
|
||||
*/
|
||||
public static final String PATH = "loader.path";
|
||||
|
||||
/**
|
||||
* Properties key for home directory. This is the location of external configuration
|
||||
* if not on classpath, and also the base path for any relative paths in the
|
||||
* {@link #PATH loader path}. Defaults to current working directory (
|
||||
* <code>${user.home}</code>).
|
||||
*/
|
||||
public static final String HOME = "loader.home";
|
||||
|
||||
/**
|
||||
* Properties key for name of external configuration file (excluding suffix). Defaults
|
||||
* to "application". Ignored if {@link #CONFIG_LOCATION loader config location} is
|
||||
* provided instead.
|
||||
*/
|
||||
public static final String CONFIG_NAME = "loader.config.name";
|
||||
|
||||
/**
|
||||
* Properties key for config file location (including optional classpath:, file: or
|
||||
* URL prefix)
|
||||
*/
|
||||
public static final String CONFIG_LOCATION = "loader.config.location";
|
||||
|
||||
private static final List<String> DEFAULT_PATHS = Arrays.asList("lib/");
|
||||
@ -188,6 +205,14 @@ public class PropertiesLauncher implements ArchiveFilter {
|
||||
finally {
|
||||
resource.close();
|
||||
}
|
||||
for (Object key : Collections.list(this.properties.propertyNames())) {
|
||||
String text = this.properties.getProperty((String) key);
|
||||
String value = SystemPropertyUtils.resolvePlaceholders(this.properties,
|
||||
text);
|
||||
if (value != null) {
|
||||
this.properties.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.logger.info("Not found: " + config);
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.boot.loader.util;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@ -61,13 +62,30 @@ public abstract class SystemPropertyUtils {
|
||||
*/
|
||||
public static String resolvePlaceholders(String text) {
|
||||
if (text == null) {
|
||||
throw new IllegalArgumentException("Argument 'value' must not be null.");
|
||||
return text;
|
||||
}
|
||||
return parseStringValue(text, text, new HashSet<String>());
|
||||
return parseStringValue(null, text, text, new HashSet<String>());
|
||||
}
|
||||
|
||||
private static String parseStringValue(String value, String current,
|
||||
Set<String> visitedPlaceholders) {
|
||||
/**
|
||||
* Resolve ${...} placeholders in the given text, replacing them with corresponding
|
||||
* system property values.
|
||||
* @param properties a properties instance to use in addition to System
|
||||
* @param text the String to resolve
|
||||
* @return the resolved String
|
||||
* @see #PLACEHOLDER_PREFIX
|
||||
* @see #PLACEHOLDER_SUFFIX
|
||||
* @throws IllegalArgumentException if there is an unresolvable placeholder
|
||||
*/
|
||||
public static String resolvePlaceholders(Properties properties, String text) {
|
||||
if (text == null) {
|
||||
return text;
|
||||
}
|
||||
return parseStringValue(properties, text, text, new HashSet<String>());
|
||||
}
|
||||
|
||||
private static String parseStringValue(Properties properties, String value,
|
||||
String current, Set<String> visitedPlaceholders) {
|
||||
|
||||
StringBuilder buf = new StringBuilder(current);
|
||||
|
||||
@ -85,9 +103,10 @@ public abstract class SystemPropertyUtils {
|
||||
// Recursive invocation, parsing placeholders contained in the
|
||||
// placeholder
|
||||
// key.
|
||||
placeholder = parseStringValue(value, placeholder, visitedPlaceholders);
|
||||
placeholder = parseStringValue(properties, value, placeholder,
|
||||
visitedPlaceholders);
|
||||
// Now obtain the value for the fully resolved key...
|
||||
String propVal = resolvePlaceholder(value, placeholder);
|
||||
String propVal = resolvePlaceholder(properties, value, placeholder);
|
||||
if (propVal == null && VALUE_SEPARATOR != null) {
|
||||
int separatorIndex = placeholder.indexOf(VALUE_SEPARATOR);
|
||||
if (separatorIndex != -1) {
|
||||
@ -95,7 +114,7 @@ public abstract class SystemPropertyUtils {
|
||||
separatorIndex);
|
||||
String defaultValue = placeholder.substring(separatorIndex
|
||||
+ VALUE_SEPARATOR.length());
|
||||
propVal = resolvePlaceholder(value, actualPlaceholder);
|
||||
propVal = resolvePlaceholder(properties, value, actualPlaceholder);
|
||||
if (propVal == null) {
|
||||
propVal = defaultValue;
|
||||
}
|
||||
@ -104,7 +123,8 @@ public abstract class SystemPropertyUtils {
|
||||
if (propVal != null) {
|
||||
// Recursive invocation, parsing placeholders contained in the
|
||||
// previously resolved placeholder value.
|
||||
propVal = parseStringValue(value, propVal, visitedPlaceholders);
|
||||
propVal = parseStringValue(properties, value, propVal,
|
||||
visitedPlaceholders);
|
||||
buf.replace(startIndex, endIndex + PLACEHOLDER_SUFFIX.length(),
|
||||
propVal);
|
||||
startIndex = buf.indexOf(PLACEHOLDER_PREFIX,
|
||||
@ -125,20 +145,23 @@ public abstract class SystemPropertyUtils {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private static String resolvePlaceholder(String text, String placeholderName) {
|
||||
private static String resolvePlaceholder(Properties properties, String text,
|
||||
String placeholderName) {
|
||||
try {
|
||||
String propVal = System.getProperty(placeholderName);
|
||||
if (propVal == null) {
|
||||
// Fall back to searching the system environment.
|
||||
propVal = System.getenv(placeholderName);
|
||||
}
|
||||
return propVal;
|
||||
if (propVal != null) {
|
||||
return propVal;
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
System.err.println("Could not resolve placeholder '" + placeholderName
|
||||
+ "' in [" + text + "] as system property: " + ex);
|
||||
return null;
|
||||
}
|
||||
return properties.getProperty(placeholderName);
|
||||
}
|
||||
|
||||
private static int findPlaceholderEndIndex(CharSequence buf, int startIndex) {
|
||||
|
@ -1,2 +1,3 @@
|
||||
loader.main: my.Application
|
||||
foo: Application
|
||||
loader.main: my.${foo}
|
||||
loader.path: etc
|
Loading…
Reference in New Issue
Block a user