英文:
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/
基本上,你需要:
- 创建你的属性源
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;
}
}
- 在启动时使用自定义环境后处理器进行注册
public class SecretStorePropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
environment.getPropertySources()
.addLast(new SecretStorePropertySource("customSecretPropertySource",
new SecretStorePropertySource()));
}
}
- 告诉 SpringBoot 使用你的自定义环境后处理器
将以下内容添加到 src/main/resources/META-INF/spring.factories
文件中
org.springframework.boot.env.EnvironmentPostProcessor=com.mycompany.myproduct.SecretStorePropertySourceEnvironmentPostProcessor
- 使用
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
- Create your property source
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;
}
}
- 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("customSecretPropertySource",
new SecretStorePropertySource()));
}
}
- 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
- 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.
Not saying I'm advising it but you also can make your code working
@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);
}
}
}
and adding following lines to application.yml
spring.datasource.username=#{@SecretUserName}
spring.datasource.password=#{@SecretUserPassword}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论