springboot 自定义属性文件拓展名(PropertySourceLoader)


springboot 自定义属性文件拓展名(PropertySourceLoader)

                    

                                        

*********************

相关类与接口

                

PropertySourceLoader

public interface PropertySourceLoader {
    String[] getFileExtensions();

    List<PropertySource<?>> load(String name, Resource resource) throws IOException;
}

                        

PropertiesPropertySourceLoader

public class PropertiesPropertySourceLoader implements PropertySourceLoader {
    private static final String XML_FILE_EXTENSION = ".xml";

    public PropertiesPropertySourceLoader() {
    }

    public String[] getFileExtensions() {
        return new String[]{"properties", "xml"};
    }  //加载properties、xml后缀的属性文件

    public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
        List<Map<String, ?>> properties = this.loadProperties(resource);
                                          //加载属性文件
        if (properties.isEmpty()) {
            return Collections.emptyList();
        } else {
            List<PropertySource<?>> propertySources = new ArrayList(properties.size());

            for(int i = 0; i < properties.size(); ++i) {
                String documentNumber = properties.size() != 1 ? " (document #" + i + ")" : "";
                propertySources.add(new OriginTrackedMapPropertySource(name + documentNumber, Collections.unmodifiableMap((Map)properties.get(i)), true));
            }  //转换为List<PropertySource<?>>

            return propertySources;
        }
    }

    private List<Map<String, ?>> loadProperties(Resource resource) throws IOException {
        String filename = resource.getFilename();
        List<Map<String, ?>> result = new ArrayList();
        if (filename != null && filename.endsWith(".xml")) {
            result.add(PropertiesLoaderUtils.loadProperties(resource));
        } else {
            List<Document> documents = (new OriginTrackedPropertiesLoader(resource)).load();
            documents.forEach((document) -> {
                result.add(document.asMap());
            });
        }

        return result;
    }
}

                   

YamlPropertySourceLoader

public class YamlPropertySourceLoader implements PropertySourceLoader {
    public YamlPropertySourceLoader() {
    }

    public String[] getFileExtensions() {
        return new String[]{"yml", "yaml"};
    }  //加载yml、yaml后缀的属性文件

    public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
        if (!ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", this.getClass().getClassLoader())) {
            throw new IllegalStateException("Attempted to load " + name + " but snakeyaml was not found on the classpath");
        } else {
            List<Map<String, Object>> loaded = (new OriginTrackedYamlLoader(resource)).load();
                                               //加载属性文件
            if (loaded.isEmpty()) {
                return Collections.emptyList();
            } else {
                List<PropertySource<?>> propertySources = new ArrayList(loaded.size());

                for(int i = 0; i < loaded.size(); ++i) {
                    String documentNumber = loaded.size() != 1 ? " (document #" + i + ")" : "";
                    propertySources.add(new OriginTrackedMapPropertySource(name + documentNumber, Collections.unmodifiableMap((Map)loaded.get(i)), true));
                }  //转换为List<PropertySource<?>>

                return propertySources;
            }
        }
    }
}

                         

                                             

PropertySource

public abstract class PropertySource<T> {
    protected final Log logger;
    protected final String name;
    protected final T source;

    public PropertySource(String name, T source) {
        this.logger = LogFactory.getLog(this.getClass());
        Assert.hasText(name, "Property source name must contain at least one character");
        Assert.notNull(source, "Property source must not be null");
        this.name = name;
        this.source = source;
    }

    public PropertySource(String name) {
        this(name, new Object());
    }

    public String getName() {
    public T getSource() {

    public boolean containsProperty(String name) {
        return this.getProperty(name) != null;
    }

    @Nullable
    public abstract Object getProperty(String var1);

    public boolean equals(@Nullable Object other) {
    public int hashCode() {
    public String toString() {

    public static PropertySource<?> named(String name) {
        return new PropertySource.ComparisonPropertySource(name);
    }

**********
内部类:ComparisonPropertySource

    static class ComparisonPropertySource extends PropertySource.StubPropertySource {
        private static final String USAGE_ERROR = "ComparisonPropertySource instances are for use with collection comparison only";

        public ComparisonPropertySource(String name) {
            super(name);
        }

        public Object getSource() {
            throw new UnsupportedOperationException("ComparisonPropertySource instances are for use with collection comparison only");
        }

        public boolean containsProperty(String name) {
            throw new UnsupportedOperationException("ComparisonPropertySource instances are for use with collection comparison only");
        }

        @Nullable
        public String getProperty(String name) {
            throw new UnsupportedOperationException("ComparisonPropertySource instances are for use with collection comparison only");
        }
    }


**********
内部类:StubPropertySource

    public static class StubPropertySource extends PropertySource<Object> {
        public StubPropertySource(String name) {
            super(name, new Object());
        }

        @Nullable
        public String getProperty(String name) {
            return null;
        }
    }
}

                        

OriginTrackedMapPropertySource

public final class OriginTrackedMapPropertySource extends MapPropertySource implements OriginLookup<String> {
    private final boolean immutable;  //默认为false

    public OriginTrackedMapPropertySource(String name, Map source) {
        this(name, source, false);
    }

    public OriginTrackedMapPropertySource(String name, Map source, boolean immutable) {
        super(name, source);
        this.immutable = immutable;
    }

    public Object getProperty(String name) {
    public Origin getOrigin(String name) {

    public boolean isImmutable() {
   
   

                               

                                                  

*********************

示例:自定义加载json后缀的属性文件加载器

                               

*****************

配置文件

                           

application.json

{
  "person.name": "瓜田李下",
  "person.age": 20
}

                   

*****************

pojo 层

                 

Person

@Data
@Component
@ConfigurationProperties("person")
public class Person {

    private String name;
    private Integer age;
}

                          

*****************

config 层

                  

CustomPropertySource

public class CustomPropertySourceLoader implements PropertySourceLoader {

    @Override
    public String[] getFileExtensions() {
        return new String[]{"json"};
    }

    @Override
    public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
        Map<String,Object> map=JSONObject.parseObject(IOUtils.toString(resource.getInputStream(), Charset.defaultCharset())).getInnerMap();
        if (map==null||map.size()==0){
            return Collections.emptyList();
        }else {
            return Collections.singletonList(new OriginTrackedMapPropertySource(name,map));
        }
    }
}

                          

src/main/resources下新建目录/META-INF,创建文件spring.factories

                            

                  

spring.factories

org.springframework.boot.env.PropertySourceLoader=\
  com.example.demo.config.CustomPropertySourceLoader

                    

*****************

controller 层

               

HelloController

@RestController
public class HelloController {

    @Resource
    private Person person;

    @RequestMapping("/hello")
    public Person hello(){
        System.out.println(person);

        return person;
    }
}

                               

                                 

*********************

使用测试

                         

localhost:8080/hello,控制台输出

2021-09-19 15:48:22.423  INFO 7952 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-09-19 15:48:22.434  INFO 7952 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 11 ms
Person(name=瓜田李下, age=20)

                             

                 

おすすめ

転載: blog.csdn.net/weixin_43931625/article/details/120374140