前提

前面写过一篇关于Environment属性加载的源码分析和扩展,里面提到属性的占位符解析和类型转换是相对复杂的,这篇文章就是要分析和解读这两个复杂的问题。关于这两个问题,选用一个比较复杂的参数处理方法PropertySourcesPropertyResolver#getProperty,解析占位符的时候依赖到
PropertySourcesPropertyResolver#getPropertyAsRawString:
protected String getPropertyAsRawString(String key) {
 return getProperty(key, String.class, false);
}
protected  T getProperty(String key, Class targetValueType, boolean resolveNestedPlaceholders) {
 if (this.propertySources != null) {
  for (PropertySource<?> propertySource : this.propertySources) {
   if (logger.isTraceEnabled()) {
    logger.trace("Searching for key '" + key + "' in PropertySource '" +
       propertySource.getName() + "'");
   }
   Object value = propertySource.getProperty(key);
   if (value != null) {
    if (resolveNestedPlaceholders && value instanceof String) {
     //解析带有占位符的属性
     value = resolveNestedPlaceholders((String) value);
    }
    logKeyFound(key, propertySource, value);
    //需要时转换属性的类型
    return convertValueIfNecessary(value, targetValueType);
   }
  }
 }
 if (logger.isDebugEnabled()) {
  logger.debug("Could not find key '" + key + "' in any property source");
 }
 return null;
}