英文:
Spring Boot parameterized configuration
问题
我正在处理一个Spring应用程序,其中在`application.properties`文件中为每一年定义了配置。基本上在这一点上,这只是一个复制粘贴的工作,只需要将粘贴的配置递增1。我们在几个类中也有类似的复制粘贴过程,为每一年的bean定义。
因为有一个要求能够访问以前年份定义的内容,我考虑提供一个当前年份的属性,然后使用某种参数化属性来定义所有的bean。不过,我并没有找到一个很好的方法来实现这一点。目前我们有:
application.properties:
year2020.datasource.jdbcUrl=jdbc:postgresql://${built.url.2020}:5432/db_name
year2020.datasource.username=some_username
year2020.datasource.password=some_password
year2020.datasource.driverClassName=org.postgresql.Driver
year2020.datasource.validationQuery=SELECT 1
并且针对其他资源和以前年份有多个类似的配置
以及一些用于bean的类:
@Configuration
public class CopyPastedDataSource {
@Bean(name = "year2020_datasource")
@ConfigurationProperties(prefix = "year2020.datasource")
public DataSource dataSource2020() {
return DataSourceBuilder.create().build();
}
@Bean(name = "year2019_datasource")
@ConfigurationProperties(prefix = "year2019.datasource")
public DataSource dataSource2020() {
return DataSourceBuilder.create().build();
}
// 以及用于以前年份的更多bean
}
我在考虑可能只是用占位符替换年份,并在运行时根据需要替换为实际年份。有没有一种更符合惯例或更可维护的实现方式呢?
英文:
I'm working with a Spring application that has configurations defined for every year in an application.properties
file. Basically at this point it's a copy-paste job, just incrementing the pasted configuration by 1. We have an analogous copy-paste process in several classes with bean definitions for every year as well.
Because there's a requirement to be able to access things defined by previous years' configurations, I'm thinking it would be simpler to provide a property for the current year, then define all the beans with some sort of parameterized properties. I'm not finding a great way to do this, though. Currently we have:
application.properties:
year2020.datasource.jdbcUrl=jdbc:postgresql://${built.url.2020}:5432/db_name
year2020.datasource.username=some_username
year2020.datasource.password=some_password
year2020.datasource.driverClassName=org.postgresql.Driver
year2020.datasource.validationQuery=SELECT 1
# And multiple similar configs for other resources and previous years
And some classes for the beans:
@Configuration
public class CopyPastedDataSource {
@Bean(name = "year2020_datasource")
@ConfigurationProperties(prefix = "year2020.datasource")
public DataSource dataSource2020() {
return DataSourceBuilder.create().build();
}
@Bean(name = "year2019_datasource")
@ConfigurationProperties(prefix = "year2019.datasource")
public DataSource dataSource2020() {
return DataSourceBuilder.create().build();
}
// And more beans for previous years
}
I was thinking maybe just replacing the year with a placeholder and replacing it with a year as needed at runtime. Is there a way to achieve this that would be more idiomatic or maintainable?
答案1
得分: 1
以下是翻译好的部分:
所以事实证明我正在寻找确切的方法:
链接:https://stackoverflow.com/a/26276872/7660079
链接:https://stackoverflow.com/a/53554102/7660079
不必逐个自动装配单独的资源,然后将它们收集到单个bean中,您可以很容易地将属性自动装配到Map中。以下是来自我们的类似编号API端点列表的示例:
application.properties
api.url.2020=api-2020.endpoint.com
api.url.2019=api-2019.endpoint.com
api.url.2018=api-2018.endpoint.com
Bean:
@Configuration
@EnableConfigurationProperties
public class ApiConfiguration {
@Bean
@ConfigurationProperties(prefix = "api.url")
public Map<Integer, String> getConfiguration() {
return new HashMap<>();
}
}
自动装配的bean:
@Component
class APIConsumer {
@Autowired
Map<Integer, String> apiUrlsByYear;
}
英文:
So it turns out I was looking for exactly this approach:
https://stackoverflow.com/a/26276872/7660079
https://stackoverflow.com/a/53554102/7660079
Instead of autowiring individual resources one by one and then collecting them into a single bean, you can autowire properties into a Map pretty easily. Here's an example from our list of similarly numbered API endpoints:
application.properties
api.url.2020=api-2020.endpoint.com
api.url.2019=api-2019.endpoint.com
api.url.2018=api-2018.endpoint.com
Bean:
@Configuration
@EnableConfigurationProperties
public class ApiConfiguration {
@Bean
@ConfigurationProperties(prefix = "api.url")
public Map<Integer, String> getConfiguration() {
return new HashMap<>();
}
}
Autowired bean:
@Component
class APIConsumer {
@Autowired
Map<Integer, String> apiUrlsByYear;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论