pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
sr.properties格式
文件路径src/main/resources/config/sr.properties
sr.mapest.key1=map1
sr.mapest.key2=map2
sr.mapest.key3=map3
sr.mapest.key4=map4
@PropertySource用法
@Component
@ConfigurationProperties(prefix = "sr")
@PropertySource(value = "classpath:/config/sr.properties", encoding = "utf-8")
public class PropertySourceConfig {
private Map<String,String> mapest = new LinkedHashMap<>();
public Map<String, String> getMapest() {
return mapest;
}
public void setMapest(Map<String, String> mapest) {
this.mapest = mapest;
}
}
测试
@RestController
public class TempController {
@Autowired
private PropertySourceConfig propertySourceConfig;
@GetMapping("/get-map")
public String getMap(String name) {
return "hello" + propertySourceConfig.getMapest().toString();
}
}
但是因为Properties类是继承的Hashtable,导致的读取时发生顺序错乱
解决方案
1)由于ResourcePropertySource不能直接更改PropertiesLoaderUtils的调用,那么需要我们按照源码顺序进行修改,即:修改PropertySourceFactory的实现,PropertiesPropertySource的实现及PropertiesLoaderUtils的方法
2)修改PropertySourceFactory的实现方法命名LinkedHashMapPropertySourceFactory
package com.example.factory;
import java.util.*;
public class LinkedHashMapProperties extends Properties {
private static final long serialVersionUID = -4627607243846121965L;
private final LinkedHashSet<Object> keys = new LinkedHashSet<>();
@Override
public Enumeration<Object> keys() {
return Collections.enumeration(keys);
}
@Override
public Object put(Object key, Object value) {
keys.add(key);
return super.put(key, value);
}
@Override
public Set<Object> keySet() {
return keys;
}
@Override
public Set<String> stringPropertyNames() {
Set<String> set = new LinkedHashSet<>();
for (Object key : this.keys) {
set.add((String) key);
}
return set;
}
}
package com.example.factory;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import java.io.IOException;
import java.util.Properties;
public class LinkedHashMapPropertiesLoaderUtils extends PropertiesLoaderUtils {
public static Properties loadProperties(EncodedResource resource) throws IOException {
Properties props = new LinkedHashMapProperties();
fillProperties(props, resource);
return props;
}
}
package com.example.factory;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import java.io.IOException;
public class LinkedHashMapPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
return (name != null ? new LinkedHashMapResourcePropertySource(name, resource) : new LinkedHashMapResourcePropertySource(resource));
}
}
package com.example.factory;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import java.io.IOException;
public class LinkedHashMapResourcePropertySource extends PropertiesPropertySource {
@Nullable
private final String resourceName;
public LinkedHashMapResourcePropertySource(String name, EncodedResource resource) throws IOException {
super(name, LinkedHashMapPropertiesLoaderUtils.loadProperties(resource));
this.resourceName = getNameForResource(resource.getResource());
}
public LinkedHashMapResourcePropertySource(EncodedResource resource) throws IOException {
super(getNameForResource(resource.getResource()), LinkedHashMapPropertiesLoaderUtils.loadProperties(resource));
this.resourceName = null;
}
private static String getNameForResource(Resource resource) {
String name = resource.getDescription();
if (!StringUtils.hasText(name)) {
name = resource.getClass().getSimpleName() + "@" + System.identityHashCode(resource);
}
return name;
}
}
修改PropertySourceConfig,@PropertySource加入属性factory
@Component
@ConfigurationProperties(prefix = "sr")
@PropertySource(value = "classpath:/config/sr.properties", encoding = "utf-8" ,factory = LinkedHashMapPropertySourceFactory.class)
public class PropertySourceConfig {
private Map<String,String> mapest = new LinkedHashMap<>();
public Map<String, String> getMapest() {
return mapest;
}
public void setMapest(Map<String, String> mapest) {
this.mapest = mapest;
}
}
--------------------------------------2021.8.13分隔线-----------------------------
有两处父类是synchronized,子类没加synchronized,没注意
public class LinkedHashMapProperties extends Properties {
private static final long serialVersionUID = -4627607243846121965L;
private final LinkedHashSet<Object> keys = new LinkedHashSet<>();
//父类是synchronized,子类还是加上比较好
@Override
public synchronized Enumeration<Object> keys() {
return Collections.enumeration(keys);
}
父类是synchronized,子类还是加上比较好
@Override
public synchronized Object put(Object key, Object value) {
keys.add(key);
return super.put(key, value);
}
@Override
public Set<Object> keySet() {
return keys;
}
@Override
public Set<String> stringPropertyNames() {
Set<String> set = new LinkedHashSet<>();
for (Object key : this.keys) {
set.add((String) key);
}
return set;
}
}
博主公众号
求关注