spring boot 配置扩展
1.
/**
* 自定义配置加载,方法定义为static的,保证优先加载
* @return
*/
@Bean
public PropertySourcesPlaceholderConfigurer propertieSources() {
final PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer() {
@Override
protected Properties mergeProperties() throws IOException {
Properties properties = super.mergeProperties();
//System.out.println("properties:"+properties);
String password=properties.getProperty("spring.datasource.password");
System.out.println("修改前的password:"+password);
properties.setProperty("spring.datasource.password","123456");
System.out.println("修改后的password:"+properties.getProperty("spring.datasource.password"));
return properties;
}
};
ppc.setIgnoreResourceNotFound(true);
final List<Resource> resourceLst = new ArrayList<Resource>();
if(System.getProperty(SPRING_CONFIG_LOCATION) != null){
String configFilePath = System.getProperty(SPRING_CONFIG_LOCATION);
String[] configFiles = configFilePath.split(",|;");
for (String configFile : configFiles) {
/* if (configFile.startsWith("file:")){
resourceLst.add(new FileSystemResource(configFile));
}else {
resourceLst.add( new ClassPathResource(configFile));
}*/
try {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
resourceLst.addAll(Arrays.asList(resolver.getResources(configFile)));
} catch (IOException e) {
e.printStackTrace();
}
}
}else {
resourceLst.add(new ClassPathResource("config/application.properties"));
}
ppc.setLocations(resourceLst.toArray(new Resource[]{}));
return ppc;
}
2. PropertySourcesPlaceholderConfigurer 源码
/**
* {@inheritDoc}
* <p>Processing occurs by replacing ${...} placeholders in bean definitions by resolving each
* against this configurer's set of {@link PropertySources}, which includes:
* <ul>
* <li>all {@linkplain org.springframework.core.env.ConfigurableEnvironment#getPropertySources
* environment property sources}, if an {@code Environment} {@linkplain #setEnvironment is present}
* <li>{@linkplain #mergeProperties merged local properties}, if {@linkplain #setLocation any}
* {@linkplain #setLocations have} {@linkplain #setProperties been}
* {@linkplain #setPropertiesArray specified}
* <li>any property sources set by calling {@link #setPropertySources}
* </ul>
* <p>If {@link #setPropertySources} is called, <strong>environment and local properties will be
* ignored</strong>. This method is designed to give the user fine-grained control over property
* sources, and once set, the configurer makes no assumptions about adding additional sources.
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (this.propertySources == null) {
this.propertySources = new MutablePropertySources();
if (this.environment != null) {
this.propertySources.addLast(
new PropertySource<Environment>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) {
@Override
public String getProperty(String key) {
return this.source.getProperty(key);
}
}
);
}
try {
//调用merageProperties方法
PropertySource<?> localPropertySource =
new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties());
if (this.localOverride) {
this.propertySources.addFirst(localPropertySource);
}
else {
this.propertySources.addLast(localPropertySource);
}
}
catch (IOException ex) {
throw new BeanInitializationException("Could not load properties", ex);
}
}
processProperties(beanFactory, new PropertySourcesPropertyResolver(this.propertySources));
this.appliedPropertySources = this.propertySources;
}
3.
/**
* Return a merged Properties instance containing both the
* loaded properties and properties set on this FactoryBean.
*/
protected Properties mergeProperties() throws IOException {
Properties result = new Properties();
if (this.localOverride) {
// Load properties from file upfront, to let local properties override.
loadProperties(result);
}
if (this.localProperties != null) {
for (Properties localProp : this.localProperties) {
CollectionUtils.mergePropertiesIntoMap(localProp, result);
}
}
//加载本地文件
if (!this.localOverride) {
// Load properties from file afterwards, to let those properties override.
loadProperties(result);
}
return result;
}
4.加载本地文件
/**
* Load properties into the given instance.
* @param props the Properties instance to load into
* @throws IOException in case of I/O errors
* @see #setLocations
*/
protected void loadProperties(Properties props) throws IOException {
if (this.locations != null) {
for (Resource location : this.locations) {
if (logger.isInfoEnabled()) {
logger.info("Loading properties file from " + location);
}
try {
PropertiesLoaderUtils.fillProperties(
props, new EncodedResource(location, this.fileEncoding), this.propertiesPersister);
}
catch (IOException ex) {
if (this.ignoreResourceNotFound) {
if (logger.isWarnEnabled()) {
logger.warn("Could not load properties from " + location + ": " + ex.getMessage());
}
}
else {
throw ex;
}
}
}
}
}