SpringBoot项目优雅的实现多配置文件切换以及获取配置信息

Posted GaoYang-笔迹

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot项目优雅的实现多配置文件切换以及获取配置信息相关的知识,希望对你有一定的参考价值。

SpringBoot项目优雅的实现多配置文件切换以及获取配置信息

在我们平时的生产中肯定不会单纯的的只有一个配置文件,通产会分为测试、开发、生产三个版本,做为一个刚入行的小白,记录一个实践中的技巧

一、构建项目

创建一个SpringBoot项目并在resources目录下创建像application-xxx.yml这样的配置文件。

进行配置文件切换

spring:
  application:
    name: test-server
  profiles:
    active: test/dev/prod ---进行切换配置文件版本

二、创建工具类进行解析yml获取对应的配置数据

  1. 创建工具类对yml进行简单的解析
public class YmlTools 
    private HashMap<String, String> ps = new LinkedHashMap<>();

    public YmlTools() 

    

    public YmlTools(Resource resource) 
        load(resource);
    

    public YmlTools(String path) 
        load(path);
    

    public YmlTools load(String path) 
        ps.putAll(new YmlParser().load(path).getAll());
        return this;
    

    public YmlTools load(Resource resource) 
        ps.putAll(new YmlParser().load(resource).getAll());
        return this;
    

    public String getProperty(String key) 
        return ps.get(key);
    

    public YmlTools clear() 
        ps.clear();
        return this;
    

    public HashMap<String, String> getAll() 
        return ps;
    

    public String dump() 
        StringBuilder sb = new StringBuilder();
        for (String key : ps.keySet()) 
            sb.append(key + ":" + ps.get(key) + "\\n");
        
        return sb.toString();
    


    public static class YmlParser 
        private HashMap<String, String> ps;
        private Pattern pattern = Pattern.compile("\\\\$\\\\[0-9a-zA-Z_\\\\.]+\\\\");


        public String getProperty(String key) 
            return ps.get(key);
        

        public HashMap<String, String> getAll() 
            return ps;
        

        public YmlParser load(Resource resource) 
            ps = parseYml(resource);
            ps = parsePos();
            return this;
        


        public YmlParser load(String path) 
            String classPathPreFix = "classpath:";
            if (path.startsWith(classPathPreFix)) 
                load(new ClassPathResource(path.substring(classPathPreFix.length())));
             else 
                load(new FileSystemResource(path));
            
            return this;
        

        private String joinPrefix(String old, String append) 
            if (old == null || old.length() <= 0) 
                return append;
            
            String rs = old + "." + append;
            if (rs.endsWith(".") || rs.endsWith(":"))
                rs = rs.substring(0, rs.length() - 1);
            return rs;
        

        private HashMap<String, String> parseYml(Resource resource) 
            HashMap<String, String> ps = new LinkedHashMap<String, String>();
            BufferedReader br = null;
            try 
                InputStream is = resource.getInputStream();
                String line = null;
                br = new BufferedReader(new InputStreamReader(is));
                String currPrefix = "";
                int lastLevel = 0;
                while ((line = br.readLine()) != null) 
                    if (line.trim().length() <= 0 || line.trim().startsWith("#"))
                        continue;
                    int leftSpace = lineLeftSpace(line);

                    boolean hasVal = line.trim().contains(": ");
                    String k = null;
                    String v = null;
                    if (hasVal) 
                        String[] kv = line.trim().split(": ");
                        k = kv[0];
                        v = kv[1];
                     else 
                        k = line.trim().split(":")[0];
                    

                    currPrefix = changeToLevel(currPrefix, leftSpace / 2);
                    currPrefix = joinPrefix(currPrefix, k);

                    if (hasVal && null != v) 
                        ps.put(currPrefix, v);
                    

                    lastLevel = leftSpace;


                
             catch (Exception ex) 
                ex.printStackTrace();
             finally 
                if (br != null)
                    try 
                        br.close();
                     catch (IOException e) 
                        e.printStackTrace();
                    
            

            return ps;
        

        private String changeToLevel(String currPrefix, int level) 
            if (null == currPrefix || currPrefix.length() <= 0 || level == 0) 
                return "";
            
            String[] grade = currPrefix.split("\\\\.");
            if (level >= grade.length) 
                return currPrefix;
            
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < level; i++) 
                if (sb.length() > 0)
                    sb.append(".");
                sb.append(grade[i]);
            
            return sb.toString();
        

        private String upPrefix(String currPrefix) 
            if (null != currPrefix) 
                if (currPrefix.contains("."))
                    currPrefix = currPrefix.substring(0, currPrefix.lastIndexOf("."));
                else
                    currPrefix = "";
            

            return currPrefix;
        

        private int lineLeftSpace(String line) 
            int l = 0;
            for (int i = 0; i < line.length(); i++) 
                if (line.charAt(i) == ' ') 
                    l++;
                 else if (line.charAt(i) == '\\t') 
                    l += 2;
                 else 
                    break;
                
            
            return l;
        

        private HashMap<String, String> parsePos() 
            HashMap<String, String> rs = new LinkedHashMap<>();
            for (String key : ps.keySet()) 
                rs.put(key, getPropertyWithParse(key));
            
            return rs;
        

        private String getPropertyWithParse(String key) 
            return replace(ps.get(key), new OnFind() 
                @Override
                public String replace(String source, String group, int start, int end) 
                    return getPropertyWithParse(group.substring(2, group.length() - 1));
                
            );
        

        private String replace(String source, OnFind onFind) 
            if(source==null)
                return source;
            
            Matcher matcher = pattern.matcher(source);
            StringBuilder sb = new StringBuilder();

            int ls = 0;
            while (matcher.find()) 
                String group = matcher.group();
                int s = matcher.start();
                int e = matcher.end();
                sb.append(source.substring(ls, s));
                sb.append(onFind.replace(source, group, s, e));
                ls = e;
            
            if (ls < source.length())
                sb.append(source.substring(ls));
            return sb.toString();
        

        public interface OnFind 
            String replace(String source, String group, int start, int end);
        
    

  1. 创建一个获取配置文件的接口
/**
 * 配置文件调用接口
 */
@Service
public interface ProjectConfigService 

    /**
     * 配置文件值取得
     *
     * @param key 配置文件键
     * @return 配置文件值
     */
    String getProperty(String key);

  1. 实现该接口
@Service
public class ProjectConfigServiceImpl implements ProjectConfigService 

    //存储配置属性的Map集合
    private Map<String, String> conf = new HashMap<String, String>();
    public ProjectConfigServiceImpl()
        conf.clear();
        conf.putAll(new YmlTools.YmlParser().load("classpath:application.yml").getAll());
        // 获取-后面的值
        String active = conf.get("spring.profiles.active");
        conf.putAll(new YmlTools.YmlParser().load("classpath:application-" + active + ".yml").getAll());
    

    public String getProperty(String key) 
        return conf.get(key);
    

三、测试

以上是关于SpringBoot项目优雅的实现多配置文件切换以及获取配置信息的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot项目优雅的实现多配置文件切换以及获取配置信息

SpringBoot项目优雅的实现多配置文件切换以及获取配置信息

springboot 多环境配置和切换

SpringBoot 的多数据源配置与动态切换

SpringBoot 的多数据源配置与动态切换

SpringBoot 的多数据源配置与动态切换