SpringBoot基础系列之自定义配置源使用姿势实例演示

SpringBoot基础系列之自定义配置源使用姿势实例演示

前面一篇博文介绍了一个@Value的一些知识点,其中提了一个点,@Value对应的配置,除了是配置文件中之外,可以从其他的数据源中获取么,如从 redis,db,http 中获取配置?

了解过 SpringCloud Config 的可以给出确切的答案,可以,而且用起来还老爽了,远程配置,支持配置动态刷新,接下来我们来看一下,在 SpringBoot 中,如何配置自定义的数据源

I. 项目环境 1. 项目依赖

本项目借助SpringBoot 2.2.1.RELEASE + maven 3.5.3 + IDEA进行开发

开一个 web 服务用于测试

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> II. 自定义配置源

@Value修饰的成员,绑定配置时,是从Envrionment中读取配置的,所以我们需要做的就是注册一个自定义的配置源,借助MapPropertySource可以来实现我们需求场景

1. 自定义数据源

演示一个最简单自定义的配置数据源,重写MapPropertySource的getProperties方法

实现如下

public class SimplePropertiesSource extends MapPropertySource { public SimplePropertiesSource(String name, Map<String, Object> source) { super(name, source); } public SimplePropertiesSource() { this("filePropertiesSource", new HashMap<>()); } /** * 覆盖这个方法,适用于实时获取配置 * * @param name * @return */ @Override public Object getProperty(String name) { // 注意,只针对自定义开头的配置才执行这个逻辑 if (name.startsWith("selfdefine.")) { return name + "_" + UUID.randomUUID(); } return super.getProperty(name); } } 2. 数据源注册

上面只是声明了配置源,接下来把它注册到 Environment 中,这样就可以供应用使用了

@RestController @SpringBootApplication public class Application { private Environment environment; @Bean public SimplePropertiesSource simplePropertiesSource(ConfigurableEnvironment environment) { this.environment = environment; SimplePropertiesSource ropertiesSource = new SimplePropertiesSource(); environment.getPropertySources().addLast(ropertiesSource); return ropertiesSource; } // 获取配置 @GetMapping(path = "get") public String getProperty(String key) { return environment.getProperty(key); } public static void main(String[] args) { SpringApplication.run(Application.class); } }

SpringBoot基础系列之自定义配置源使用姿势实例演示

从上面的输出可以看出,自定义配置开头的会获取到随机的配置值;非selfdefine开头的,没有相应的配置,返回空

3. 基于文件的自定义配置源

上面这个可能有点过于儿戏了,接下来我们将配置源放在自定义的文件中,并支持文件配置修改

public class FilePropertiesSource extends MapPropertySource { public FilePropertiesSource(String name, Map<String, Object> source) { super(name, source); } public FilePropertiesSource() { this("filePropertiesSource", new HashMap<>()); } // 这种方式,适用于一次捞取所有的配置,然后从内存中查询对应的配置,提高服务性能 // 10s 更新一次 @PostConstruct @Scheduled(fixedRate = 10_000) public void refreshSource() throws IOException { String ans = FileCopyUtils.copyToString(new InputStreamReader(FilePropertiesSource.class.getClassLoader().getResourceAsStream("kv.properties"))); Map<String, Object> map = new HashMap<>(); for (String sub : ans.split("\n")) { if (sub.isEmpty()) { continue; } String[] kv = StringUtils.split(sub, "="); if (kv.length != 2) { continue; } map.put(kv[0].trim(), kv[1].trim()); } source.clear(); source.putAll(map); } }

上面写了一个定时器,每 10s 刷新一下内存中的配置信息,当然这里也是可以配置一个文件变动监听器,相关有兴趣的话,可以看下

对应的配置文件

user=xhh name=一灰灰 age=18

注册的姿势与上面一致,就不单独说明了,接下来演示一下使用

SpringBoot基础系列之自定义配置源使用姿势实例演示

从上可以看到文件中的配置修改之后,过一段时间会刷新

4. @Value绑定自定义配置

接下来我们看一下,将@Value绑定自定义的配置,是否可以成功

调整一下上面的 Application, 添加一个成员属性

@Value("${name}") private String name; @GetMapping(path = "get") public String getProperty(String key) { return name + "|" + environment.getProperty(key); }

再次测试发现抛异常了,说是这个配置不存在!!!

SpringBoot基础系列之自定义配置源使用姿势实例演示

(这就过分了啊,看了半天,结果告诉我不行,这还不得赶紧搞个差评么

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzfgpf.html