当前位置: 首页 > 知识库问答 >
问题:

带有Spring Cloud配置的自定义属性加载器

晏阳飙
2023-03-14

我在我的SpringBoot应用程序中使用SpringCloud配置,我需要编写一些自定义代码来处理属性,当属性被标记为这样时,这些属性将从我的公司密码库中读取。我知道SpringCloud支持Hashicorp Vault,但在这种情况下不是这样的。

我不想硬编码从不同的源检索特定的属性,例如,我会为应用程序app1创建一个属性文件,其中profiledev的值为:

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

但对于其他一些配置文件,如prod,我会:

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=prod-user
spring.datasource.password=[[vault]]
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

因此,我需要自定义属性vault在发现返回值等于[[vault]](或其他类型的标志)时拦截加载的属性,并从公司vault进行查询。在本例中,我的自定义属性加载器将查找属性spring的值。数据源。密码来自公司密码保险库。所有其他属性仍将按原样从标准SpringCloudConfigClient加载的值返回。

我希望只使用带注释的代码,而不使用XML配置。

共有2个答案

万嘉石
2023-03-14

在试图解决同样的问题时,我相信我已经找到了可以接受的解决办法。

下面是我的解决方案。

public class JBossVaultEnvironmentPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
    MutablePropertySources propertySources = environment.getPropertySources();
    Map<String, String> sensitiveProperties = propertySources.stream()
            .filter(propertySource -> propertySource instanceof EnumerablePropertySource)
            .map(propertySource -> (EnumerablePropertySource<?>) propertySource)
            .map(propertySource -> {
                Map<String, String> vaultProperties = new HashMap<>();
                String[] propertyNames = propertySource.getPropertyNames();
                for (String propertyName : propertyNames) {
                    String propertyValue = propertySource.getProperty(propertyName).toString();
                    if (propertyValue.startsWith("VAULT::")) {
                        vaultProperties.put(propertyName, propertyValue);
                    }
                }
                return vaultProperties;
            })
            .reduce(new HashMap<>(), (m1, m2) -> {
                m1.putAll(m2);
                return m1;
            });

    Map<String, Object> vaultProperties = new HashMap<>();
    sensitiveProperties.keySet().stream()
            .forEach(key -> {
                vaultProperties.put(key, VaultReader.readAttributeValue(sensitiveProperties.get(key)));
            });

    propertySources.addFirst(new MapPropertySource("vaultProperties", vaultProperties));
}
松茂实
2023-03-14

您可以实现自己的PropertySourceLocator并向spring添加条目。META-INF目录中的工厂。

#spring.factories

org.springframework.cloud.bootstrap.BootstrapConfiguration=/
foo.bar.MyPropertySourceLocator

然后你可以像Spring的普通属性一样引用公司密码库中的密钥。

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=prod-user
spring.datasource.password=${lodaded.password.from.corporate.vault}
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

HasiCorp的实现:Vault属性资源定位器支持

 类似资料:
  • 在Spring Boot中,有一个属性文件application.property,与这个属性一起,我创建了一个额外的属性文件,名为MyOwnProp.properties。 如何在中加载?表示如何在Application.properties中包含另一个命名属性? 有什么进展吗?

  • 1. 预置事件 预置事件是百度统计的基础代码能够获取到的基础事件,如页面浏览、元素点击等。系统为预置事件页面浏览、元素点击、session默认关联了预置属性。 这个功能支持您给页面浏览、元素点击、session添加自定义属性。 适用场景: 标识访问状态:是否为登录用户、是否为试用用户 标识访问来源:查看不同来源媒体的用户行为 标识页面分组:按网页作者分组、按页面标题分组、按网页内容分组 该功能替换

  • 问题内容: 我有一个Java类,它在启动时基于javassist类加载器创建自定义类加载器,然后运行实际的程序类。我收到以下错误: 该问题与以下事实有关:一个对象是由原始类加载器创建的,而另一个是由自定义类创建的。 有没有办法解决此错误? 在此先感谢 Avner 问题答案: 请尝试将-Dlog4j.ignoreTCL =true设置为希望有帮助。关于log4j的类似问题

  • 我使用的是带有默认属性文件的Spring Boot2.0。我想把它拆分到不同的属性文件中,因为它变得很大。 我还想编写测试来检查属性的正确性:将在生产应用程序上下文(而不是测试上下文)上显示的值。 下面是我的属性文件:src/main/resources/config/custom.yml 但是测试失败并出现错误: 此外,通过在中打印应用程序,我看到在运行应用程序时,属性值为。 当我对所有属性使用

  • 1. 预置事件 预置事件是百度统计的基础代码能够获取到的基础事件,如页面浏览、元素点击等。系统为预置事件页面浏览、元素点击、session默认关联了预置属性。 这个功能支持您给页面浏览、元素点击、session添加自定义属性。 适用场景: 标识访问状态:是否为登录用户、是否为试用用户 标识访问来源:查看不同来源媒体的用户行为 标识页面分组:按网页作者分组、按页面标题分组、按网页内容分组 该功能替换

  • 这就是所谓的扩展枚举。我知道它管用--我以前试过并用过很多次。我知道如果这是您应该对枚举做的事情,可能会有讨论--我认为是的,因为您仍然有您定义的常量,但它们只是包含了一些更多的信息(仍然是常量)。(另外:我看过这个例子,java枚举上的自定义字段没有序列化,我认为它们也遵循了我在如何生成枚举上的自定义属性方面的思路)。 现在,我究竟应该如何从Eclipse EMF模型生成这样的东西呢?我甚至不知