Spring 启动 - 配置未被读取?

Spring Boot - configuration not being read?

我正在使用 springboot 2.0.4.RELEASE 并尝试为我的应用程序配置数据库属性。我添加了一个新的配置文件如下:

@Configuration
@ConfigurationProperties(prefix="spring.datasource")
public class DatabaseConfig 
{
    private String userName;
    private String password;
    
    public String getUserName() {
        try {
            userName = Files.readAllLines(Paths.get("/secrets/username.txt")).get(0);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        try {
            password = Files.readAllLines(Paths.get("/secrets/password.txt")).get(0);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

这是我的 application.properties

spring.datasource.url=jdbc:sqlserver://mno35978487001.cloud.xyz.com:14481
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

我希望当应用程序运行时,application.properties 将能够从文件中读取用户名和密码,但这似乎没有发生。对我所缺少的有什么想法吗?有没有更好的方法来读取这些值并动态设置它们?

您可以创建环境变量并在 application.properties 中使用占位符来引用它们,而不是读取 txt 文件:

spring.datasource.username: ${USERNAME}
spring.datasource.password: ${PASSWORD}

您可以阅读有关占位符的更多信息here

您可以添加自定义 属性 源定位器。

https://source.coveo.com/2018/08/03/spring-boot-and-aws-parameter-store/

基本上,你需要

  1. 创建您的 属性 来源
    public class SecretStorePropertySource extends PropertySource<SecretStoreSource> {
    
        public SecretStorePropertySource(String name) {
            super(name);
        }
    
        @Override
        public Object getProperty(String name) {
            if (name.startsWith("secrets.")) {
                // converts property name into file name, 
                // e.g. secrets.username -> /secrets/username.txt
                return Files.readAllLines(Paths.get("/"+name.replace('.','/')+".txt")).get(0);           
            }
            return null;
        }
    }
  1. 在开始使用自定义环境时注册它 post 处理器
    public class SecretStorePropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor {
    
        @Override
        public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
            environment.getPropertySources()
                    .addLast(new SecretStorePropertySource("customSecretPropertySource",
                            new SecretStorePropertySource()));
        }
    }
  1. 告诉 SpringBoot 使用你自定义的环境post处理器

添加到 src/main/resources/META-INF/spring.factories 文件

org.springframework.boot.env.EnvironmentPostProcessor=com.mycompany.myproduct.SecretStorePropertySourceEnvironmentPostProcessor
  1. 使用 secrets. 前缀通过您的来源传递 属性
spring.datasource.username=${secrets.username}
spring.datasource.password=${secrets.password}

但是,如果您要通过文件提供它,则只需将此文件重命名为 application-secrets.yml 并放置在目标服务器上的 config 文件夹中,该文件夹本身位于应用程序 jar 所在的同一文件夹中已复制。

现在您可以通过将 secrets 添加到活动配置文件列表来要求 SpringBoot 加载它。

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-profile-specific-properties

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-adding-active-profiles

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-set-active-spring-profiles


不是说我在建议它,但你也可以让你的代码工作

@Configuration
public class Secrets {
    @Bean("SecretUserName")
    public String getUserName() {
        try {
            return Files.readAllLines(Paths.get("/secrets/username.txt")).get(0);
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }

    @Bean("SecretUserPassword")
    public String getPassword() {
        try {
            return Files.readAllLines(Paths.get("/secrets/password.txt")).get(0);
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }
}

并将以下行添加到 application.yml

spring.datasource.username=#{@SecretUserName}
spring.datasource.password=#{@SecretUserPassword}