📄 propertyplaceholderconfigurer.java
字号:
this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
}
/**
* Only necessary to check that we're not parsing our own bean definition,
* to avoid failing on unresolvable placeholders in properties file locations.
* The latter case can happen with placeholders for system properties in
* resource locations.
* @see #setLocations
* @see org.springframework.core.io.ResourceEditor
*/
public void setBeanName(String beanName) {
this.beanName = beanName;
}
/**
* Only necessary to check that we're not parsing our own bean definition,
* to avoid failing on unresolvable placeholders in properties file locations.
* The latter case can happen with placeholders for system properties in
* resource locations.
* @see #setLocations
* @see org.springframework.core.io.ResourceEditor
*/
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
throws BeansException {
BeanDefinitionVisitor visitor = new PlaceholderResolvingBeanDefinitionVisitor(props);
String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
for (int i = 0; i < beanNames.length; i++) {
// Check that we're not parsing our own bean definition,
// to avoid failing on unresolvable placeholders in properties file locations.
if (!(beanNames[i].equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) {
BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(beanNames[i]);
try {
visitor.visitBeanDefinition(bd);
}
catch (BeanDefinitionStoreException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanNames[i], ex.getMessage());
}
}
}
}
/**
* Parse the given String value recursively, to be able to resolve
* nested placeholders (when resolved property values in turn contain
* placeholders again).
* @param strVal the String value to parse
* @param props the Properties to resolve placeholders against
* @param originalPlaceholder the original placeholder, used to detect
* circular references between placeholders. Only non-null if we're
* parsing a nested placeholder.
* @throws BeanDefinitionStoreException if invalid values are encountered
* @see #resolvePlaceholder(String, java.util.Properties, int)
*/
protected String parseStringValue(String strVal, Properties props, String originalPlaceholder)
throws BeanDefinitionStoreException {
StringBuffer buf = new StringBuffer(strVal);
// The following code does not use JDK 1.4's StringBuffer.indexOf(String)
// method to retain JDK 1.3 compatibility. The slight loss in performance
// is not really relevant, as this code will typically just run on startup.
int startIndex = strVal.indexOf(this.placeholderPrefix);
while (startIndex != -1) {
int endIndex = buf.toString().indexOf(
this.placeholderSuffix, startIndex + this.placeholderPrefix.length());
if (endIndex != -1) {
String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex);
String originalPlaceholderToUse = null;
if (originalPlaceholder != null) {
originalPlaceholderToUse = originalPlaceholder;
if (placeholder.equals(originalPlaceholder)) {
throw new BeanDefinitionStoreException(
"Circular placeholder reference '" + placeholder + "' in property definitions");
}
}
else {
originalPlaceholderToUse = placeholder;
}
String propVal = resolvePlaceholder(placeholder, props, this.systemPropertiesMode);
if (propVal != null) {
// Recursive invocation, parsing placeholders contained in the
// previously resolved placeholder value.
propVal = parseStringValue(propVal, props, originalPlaceholderToUse);
buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
if (logger.isDebugEnabled()) {
logger.debug("Resolved placeholder '" + placeholder + "' to value [" + propVal + "]");
}
startIndex = buf.toString().indexOf(this.placeholderPrefix, startIndex + propVal.length());
}
else if (this.ignoreUnresolvablePlaceholders) {
// Proceed with unprocessed value.
startIndex = buf.toString().indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
}
else {
throw new BeanDefinitionStoreException("Could not resolve placeholder '" + placeholder + "'");
}
}
else {
startIndex = -1;
}
}
return buf.toString();
}
/**
* Resolve the given placeholder using the given properties, performing
* a system properties check according to the given mode.
* <p>Default implementation delegates to <code>resolvePlaceholder
* (placeholder, props)</code> before/after the system properties check.
* <p>Subclasses can override this for custom resolution strategies,
* including customized points for the system properties check.
* @param placeholder the placeholder to resolve
* @param props the merged properties of this configurer
* @param systemPropertiesMode the system properties mode,
* according to the constants in this class
* @return the resolved value, of null if none
* @see #setSystemPropertiesMode
* @see System#getProperty
* @see #resolvePlaceholder(String, java.util.Properties)
*/
protected String resolvePlaceholder(String placeholder, Properties props, int systemPropertiesMode) {
String propVal = null;
if (systemPropertiesMode == SYSTEM_PROPERTIES_MODE_OVERRIDE) {
propVal = resolveSystemProperty(placeholder);
}
if (propVal == null) {
propVal = resolvePlaceholder(placeholder, props);
}
if (propVal == null && systemPropertiesMode == SYSTEM_PROPERTIES_MODE_FALLBACK) {
propVal = resolveSystemProperty(placeholder);
}
return propVal;
}
/**
* Resolve the given placeholder using the given properties.
* Default implementation simply checks for a corresponding property key.
* <p>Subclasses can override this for customized placeholder-to-key mappings
* or custom resolution strategies, possibly just using the given properties
* as fallback.
* <p>Note that system properties will still be checked before respectively
* after this method is invoked, according to the system properties mode.
* @param placeholder the placeholder to resolve
* @param props the merged properties of this configurer
* @return the resolved value, of <code>null</code> if none
* @see #setSystemPropertiesMode
*/
protected String resolvePlaceholder(String placeholder, Properties props) {
return props.getProperty(placeholder);
}
/**
* Resolve the given key as JVM system property, and optionally also as
* system environment variable if no matching system property has been found.
* @param key the placeholder to resolve as system property key
* @return the system property value, or <code>null</code> if not found
* @see #setSearchSystemEnvironment
* @see java.lang.System#getProperty(String)
* @see java.lang.System#getenv(String)
*/
protected String resolveSystemProperty(String key) {
String value = System.getProperty(key);
if (value == null && this.searchSystemEnvironment) {
value = System.getenv(key);
}
return value;
}
/**
* BeanDefinitionVisitor that resolves placeholders in String values,
* deleagating to the <code>parseStringValue</code> method of the
* containing clas.
*/
private class PlaceholderResolvingBeanDefinitionVisitor extends BeanDefinitionVisitor {
private final Properties props;
public PlaceholderResolvingBeanDefinitionVisitor(Properties props) {
this.props = props;
}
protected String resolveStringValue(String strVal) throws BeansException {
return parseStringValue(strVal, this.props, null);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -