春季启动参数化配置

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

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 = &quot;api.url&quot;)
    public Map&lt;Integer, String&gt; getConfiguration() {
        return new HashMap&lt;&gt;();
    }
}

Autowired bean:

@Component
class APIConsumer {
    @Autowired
    Map&lt;Integer, String&gt; apiUrlsByYear;
}

huangapple
  • 本文由 发表于 2020年9月30日 00:57:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/64124273.html
匿名

发表评论

匿名网友

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

确定