Spring Boot – 配置未被读取?

huangapple go评论109阅读模式
英文:

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 将能够从文件中读取用户名和密码,但似乎并没有发生。对于我漏掉了什么,你有什么想法吗?有没有更好的方法来读取这些值并动态地设置它们?

英文:

I am using springboot 2.0.4.RELEASE and am trying to configure database properties for my app. I added a new configuration file as follows:

@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;
	}
}

Here's my 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

I was hoping when the application runs, application.properties will be able to read the user name and password from the file but that doesn't seem to happen. Any thoughts on what I am missing? Are there any better ways of reading those values and setting them dynamically?

答案1

得分: 3

代替读取txt文件,您可以使用环境变量,并在您的application.properties中使用占位符来引用它们:

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

您可以在此处阅读有关占位符的更多信息(链接):https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/html/boot-features-external-config.html#boot-features-external-config-placeholders-in-properties

英文:

Instead of reading txt files you could make environment variables and use placeholders in your application.properties to reference them:

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

You can read more about placeholders here.

答案2

得分: 3

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

链接: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.")) {
            // 将属性名转换为文件名,
            // 例如 secrets.username -> /secrets/username.txt
            return Files.readAllLines(Paths.get("/" + name.replace('.', '/') + ".txt")).get(0);     		 
        }
        return null;
    }
}
  1. 在启动时使用自定义环境后处理器进行注册
public class SecretStorePropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor {
    
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        environment.getPropertySources()
            .addLast(new SecretStorePropertySource("customSecretPropertySource",
                    new SecretStorePropertySource()));
    }
}
  1. 告诉 SpringBoot 使用你的自定义环境后处理器

将以下内容添加到 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}
英文:

You can add custom property source locator.

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

Basically, you need

  1. Create your property source
    public class SecretStorePropertySource extends PropertySource&lt;SecretStoreSource&gt; {
    
    	public SecretStorePropertySource(String name) {
    		super(name);
    	}
    
    	@Override
    	public Object getProperty(String name) {
    		if (name.startsWith(&quot;secrets.&quot;)) {
                // converts property name into file name, 
                // e.g. secrets.username -&gt; /secrets/username.txt
    			return Files.readAllLines(Paths.get(&quot;/&quot;+name.replace(&#39;.&#39;,&#39;/&#39;)+&quot;.txt&quot;)).get(0);     		 
            }
    		return null;
    	}
    }
  1. Register it on start using custom environment post processor
    public class SecretStorePropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor {
    
    	@Override
    	public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
    		environment.getPropertySources()
    				.addLast(new SecretStorePropertySource(&quot;customSecretPropertySource&quot;,
    						new SecretStorePropertySource()));
    	}
    }
  1. Tell SpringBoot to use your custom environment post processor

Add to src/main/resources/META-INF/spring.factories file

org.springframework.boot.env.EnvironmentPostProcessor=com.mycompany.myproduct.SecretStorePropertySourceEnvironmentPostProcessor
  1. Use secrets. prefix to pass property through your source
spring.datasource.username=${secrets.username}
spring.datasource.password=${secrets.password}

However, if you are going to provide it via file then just rename this file to application-secrets.yml and place on target server into config folder which itself is located in the same folder where application jar copied.

Now you can ask SpringBoot to load it by adding secrets into active profiles list.

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


Not saying I'm advising it but you also can make your code working

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

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

and adding following lines to application.yml

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

huangapple
  • 本文由 发表于 2020年8月29日 06:47:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/63641764.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定