栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Boot、Spring Cloud 自定义配置文件(如何整合配置中心)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Boot、Spring Cloud 自定义配置文件(如何整合配置中心)

文章目录
    • Spring Boot配置
    • 简单测试使用
    • Spring Cloud自定义配置文件获取
      • 1. 引入依赖
      • 2. 自定义配置
        • 2.1 自定义PropertySource,这里我们直接使用Spring 提供的MapPropertySource
        • 2.2 自定义PropertySourceLocator
        • 2.3 自定义配置Bean config
        • 2.4 定义BootstrapConfiguration配置
      • 3. 测试
    • 总结

这里是weihubeats,觉得文章不错可以关注公众号小奏技术,文章首发。拒绝营销号,拒绝标题党

Spring Boot配置

在spring中我们都知道所有配置定义在配置文件application.yml中我们就可以通过注解获取到。
Spring 中对所有配置管理都有一个统一的上层接口

  • Environment

实现类图

可以看到实现类是非常多的。不过实际所有的配置获取都是封装在最上层的接口PropertyResolver中的

这里需要注意的是PropertyResolver的核心实现类PropertySourcesPropertyResolver

而PropertySourcesPropertyResolver中拥有的PropertySources最后使用的也还是PropertySource类,通过遍历PropertySource集合

而PropertySource最终是通过拥有一个泛型T source获取最终的属性

所以这里可以看到我们所有的资源都是一个PropertySource
需要注意的是,PropertySource之间是有优先级顺序的,如果有一个Key在多个PropertySource中都存在,那么在前面的PropertySource优先。

大致获取的原理这里引用apollo的一张图

这张图就是比较清晰的

简单测试使用

spring boot 版本 2.6.8

yaml 配置一个name属性

name: 1214
@RestController
public class EnvironementController {
    @Autowired
    Environment environment;
    
	@Value("${name}")
    private String name;

    @GetMapping("/name")
    public String env(){
        System.out.println(name);
        return environment.getProperty("name");
    }
}

无论是使用@Value还是Environment都能获取到我们的自定义属性

然后调用接口就能获取到我们配置中的属性了

Spring Cloud自定义配置文件获取

在了解了上面的原理及基本使用之后我们可以就可以自定义配置文件了。核心思路就是通过读取文件然后加载到PropertySource中去。
而Spring Cloud刚好提供类这方面的扩展,Spring Cloud 提供了PropertySourceLocator接口供我们加载自定义配置成PropertySource

我们这里只需要实现locate即可

按这个方式我们来自定义配置试试

1. 引入依赖
	
        UTF-8
        1.8
        1.8    
        2021.0.2
        2.7.0

    

		
            org.springframework.cloud
            spring-cloud-context
        
        
            org.springframework.cloud
            spring-cloud-starter
        
        
            org.springframework.cloud
            spring-cloud-starter-bootstrap
        
        
            org.springframework.boot
            spring-boot-starter-web
        
		
		
        
            
                org.springframework.boot
                spring-boot-dependencies
                ${spring-boot.version}
                pom
                import
            
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
                  
        

    

注意spring Cloud 2020版本后需要手动引入依赖 spring-cloud-starter-bootstrap

2. 自定义配置 2.1 自定义PropertySource,这里我们直接使用Spring 提供的MapPropertySource
package com.zou.config;

import java.util.Map;

import org.springframework.core.env.MapPropertySource;


public class ZouMapPropertySource extends MapPropertySource {


	
	public ZouMapPropertySource(String name, Map source) {
		super(name, source);
	}
	
	
}
2.2 自定义PropertySourceLocator
package com.zou.config;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.boot.json.JsonParser;
import org.springframework.boot.json.JsonParserFactory;
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource;


@Order(0)
public class ZouJsonPropertySourceLocator implements PropertySourceLocator {

	@Override
	public PropertySource locate(Environment environment) {
		return new ZouMapPropertySource
				("ZouMapPropertySource", mapPropertySource());
	}

	private Map mapPropertySource() {
		Map result = new HashMap<>();
		JsonParser parser = JsonParserFactory.getJsonParser();
		Map fileMap = parser.parseMap(readFile());
		processNestMap("", result, fileMap);
		return result;
	}

	
	private String readFile() {
		List lines;
		try {
			lines = Files.readAllLines(Paths.get("src/main/resources/zou.json"), StandardCharsets.UTF_8);
		}
		catch (IOException e) {
			throw new RuntimeException(e);
		}
		StringBuilder sb = new StringBuilder();
		for (String line : lines) {
			sb.append(line);
		}
		return sb.toString();
	}

	private void processNestMap(String prefix, Map result, Map fileMap) {
		if (prefix.length() > 0) {
			prefix += ".";
		}
		for (Map.Entry entrySet : fileMap.entrySet()) {
			if (entrySet.getValue() instanceof Map) {
				processNestMap(prefix + entrySet.getKey(), result, (Map) entrySet.getValue());
			}
			else {
				result.put(prefix + entrySet.getKey(), entrySet.getValue());
			}
		}
	}

}

2.3 自定义配置Bean config
@Configuration(proxyBeanMethods = false)
public class ZouConfiguration {

	@Bean
	public ZouJsonPropertySourceLocator zouJsonPropertySourceLocator(){
		return new ZouJsonPropertySourceLocator();
	}
}
2.4 定义BootstrapConfiguration配置

在resources 添加spring.factories配置文件

org.springframework.cloud.bootstrap.BootstrapConfiguration=
com.zou.config.ZouConfiguration
3. 测试

这里简单定义一个我们自己的配置文件zou.json

{
  "name": "xiaozou"
}

定义一个测试controller

@RestController
@RequestMapping("test/v1")
public class ZouController {
	@Autowired
    Environment environment;

    @Value("${name:1}")
    private String name;

    @GetMapping("/name")
    public String env(){
        System.out.println(name);
        return environment.getProperty("name");
    }
}


可以看到我们自定义配置是生效了的

总结

Spring Cloud 整合自定义配置还是比较容易的,核心还是自定义一个ZouJsonPropertySourceLocator然后加载PropertySource到Spring中。这里我们整合的是本地文件,其实如果要整合远程配置中心也是类似的,只不过获取文件就不是读取本地配置文件,而是通过http读取远程配置文件然后构造出一个PropertySource放入Spring容器中。后续有机会我们对nacos整合Spring Cloud源码进行分析

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1013659.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号