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

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

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. 引入依赖

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>    
        <spring-cloud.version>2021.0.2</spring-cloud.version>
        <spring-boot.version>2.7.0</spring-boot.version>
    </properties>
    <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>      
        </dependencies>
    </dependencyManagement>

注意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;
/**
 *@author : wh
 *@date : 2022/7/12 09:54
 *@description:
 */
public class ZouMapPropertySource extends MapPropertySource {
  /**
   * Create a new {@code MapPropertySource} with the given name and {@code Map}.
   *
   * @param name   the associated name
   * @param source the Map source (without {@code null} values in order to get
   *               consistent {@link #getProperty} and {@link #containsProperty} behavior)
   */
  public ZouMapPropertySource(String name, Map<String, Object> 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;
/**
 * @author : wh
 * @date : 2022/7/12 09:56
 * @description:
 */
@Order(0)
public class ZouJsonPropertySourceLocator implements PropertySourceLocator {
  @Override
  public PropertySource<?> locate(Environment environment) {
    return new ZouMapPropertySource
        ("ZouMapPropertySource", mapPropertySource());
  }
  private Map<String, Object> mapPropertySource() {
    Map<String, Object> result = new HashMap<>();
    JsonParser parser = JsonParserFactory.getJsonParser();
    Map<String, Object> fileMap = parser.parseMap(readFile());
    processNestMap("", result, fileMap);
    return result;
  }
  /**
   * 读取配置文件 zou.json
   *
   * @return
   */
  private String readFile() {
    List<String> 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<String, Object> result, Map<String, Object> fileMap) {
    if (prefix.length() > 0) {
      prefix += ".";
    }
    for (Map.Entry<String, Object> entrySet : fileMap.entrySet()) {
      if (entrySet.getValue() instanceof Map) {
        processNestMap(prefix + entrySet.getKey(), result, (Map<String, Object>) 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 源码进行分析

相关文章
|
12天前
|
存储 前端开发 Java
Springboot静态资源映射及文件映射
在Spring Boot项目中,为了解决前端访问后端存储的图片问题,起初尝试通过静态资源映射实现,但发现这种方式仅能访问打包时已存在的文件。对于动态上传的图片(如头像),需采用资源映射配置,将特定路径映射到服务器上的文件夹,确保新上传的图片能即时访问。例如,通过`addResourceHandler(&quot;/img/**&quot;).addResourceLocations(&quot;file:E:\\myProject\\forum_server\\&quot;)`配置,使前端可通过URL直接访问图片。
Springboot静态资源映射及文件映射
|
24天前
|
监控 Java 应用服务中间件
SpringBoot是如何简化Spring开发的,以及SpringBoot的特性以及源码分析
Spring Boot 通过简化配置、自动配置和嵌入式服务器等特性,大大简化了 Spring 应用的开发过程。它通过提供一系列 `starter` 依赖和开箱即用的默认配置,使开发者能够更专注于业务逻辑而非繁琐的配置。Spring Boot 的自动配置机制和强大的 Actuator 功能进一步提升了开发效率和应用的可维护性。通过对其源码的分析,可以更深入地理解其内部工作机制,从而更好地利用其特性进行开发。
42 6
|
1月前
|
Java 测试技术 应用服务中间件
Spring Boot 配置文件总结
Spring Boot 提供全局配置文件 `application.properties` 和 `application.yml`,用于修改自动配置的默认值。前者使用键值对配置,后者使用缩进和冒号。不同环境(开发、测试、生产)可切换配置文件,通过 `spring.profiles.active` 指定。例如,开发环境端口为4790,测试环境为4791,生产环境为4792。配置示例展示了属性、List、Map定义及引用方法。
64 14
|
1月前
|
缓存 安全 Java
Spring Boot 3 集成 Spring Security + JWT
本文详细介绍了如何使用Spring Boot 3和Spring Security集成JWT,实现前后端分离的安全认证概述了从入门到引入数据库,再到使用JWT的完整流程。列举了项目中用到的关键依赖,如MyBatis-Plus、Hutool等。简要提及了系统配置表、部门表、字典表等表结构。使用Hutool-jwt工具类进行JWT校验。配置忽略路径、禁用CSRF、添加JWT校验过滤器等。实现登录接口,返回token等信息。
375 12
|
2月前
|
XML Java 数据格式
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
本文介绍了在使用Spring框架时,如何通过创建`applicationContext.xml`配置文件来管理对象。首先,在resources目录下新建XML配置文件,并通过IDEA自动生成部分配置。为完善配置,特别是添加AOP支持,可以通过IDEA的Live Templates功能自定义XML模板。具体步骤包括:连续按两次Shift搜索Live Templates,配置模板内容,输入特定前缀(如spring)并按Tab键即可快速生成完整的Spring配置文件。这样可以大大提高开发效率,减少重复工作。
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
|
1月前
|
存储 安全 Java
Spring Boot 3 集成Spring AOP实现系统日志记录
本文介绍了如何在Spring Boot 3中集成Spring AOP实现系统日志记录功能。通过定义`SysLog`注解和配置相应的AOP切面,可以在方法执行前后自动记录日志信息,包括操作的开始时间、结束时间、请求参数、返回结果、异常信息等,并将这些信息保存到数据库中。此外,还使用了`ThreadLocal`变量来存储每个线程独立的日志数据,确保线程安全。文中还展示了项目实战中的部分代码片段,以及基于Spring Boot 3 + Vue 3构建的快速开发框架的简介与内置功能列表。此框架结合了当前主流技术栈,提供了用户管理、权限控制、接口文档自动生成等多项实用特性。
85 8
|
2月前
|
缓存 前端开发 Java
【Spring】——SpringBoot项目创建
SpringBoot项目创建,SpringBootApplication启动类,target文件,web服务器,tomcat,访问服务器
|
2月前
|
消息中间件 监控 Java
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
48 6
|
2月前
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
210 5
|
2月前
|
Java 关系型数据库 MySQL
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
81 5