英文:
Spring choose property source by a combination of profiles
问题
Sure, here's the translated content:
我有多个由Spring配置文件驱动的环境,例如 `application-int.yml`、`application-dev.yml` 等,内容类似:
- `application-int.yml`
   ```yaml
   ws:
     endpoint: http://my-soap-int-endpoint.com/
     mock: http://my-soap-int-mock-endpoint.com/
application-dev.ymlws: endpoint: http://my-soap-dev-endpoint.com/ mock: http://my-soap-dev-mock-endpoint.com/
我的目标是基于环境名称和是否包含 mock 配置,使用以下属性之一:
- 对于 
dev环境,使用application-dev.yml中的ws.endpoint - 对于 
int环境,使用application-int.yml中的ws.endpoint - 对于 
dev mock环境,使用application-dev.yml中的ws.mock - 对于 
int mock环境,使用application-int.yml中的ws.mock 
我需要将该值解析到单个变量 url 中:
@Configuration
public class SoapConfiguration {
    @Value("${wsUrl}")                  // 基于两个属性
    private String wsUrl;
}
我希望避免仅基于 @Profile 创建复杂的抽象配置类层次结构。此外,我需要将模拟和非模拟变量都放在一个通用的属性文件中。有没有既可读又易于维护的好方法呢?
<details>
<summary>英文:</summary>
I have multiple environments driven by Spring profiles, such as `application-int.yml`, `application-dev.yml` etc with similar content:
- `application-int.yml`
ws:
endpoint: http://my-soap-int-endpoint.com/
mock: http://my-soap-int-mock-endpoint.com/
- `application-dev.yml`
ws:
endpoint: http://my-soap-dev-endpoint.com/
mock: http://my-soap-dev-mock-endpoint.com/
My goal is to use the following property based on **both** the environment name **and** whether the `mock` profile is included:
- `ws.endpoint` from `application-dev.yml` for `dev` profiles
- `ws.endpoint` from `application-int.yml` for `int` profiles
- `ws.mock` from `application-dev.yml` for `dev mock` profiles
- `ws.mock` from `application-int.yml` for `int mock` profiles
I need to parse that value into a single variable `url`:
@Configuration
public class SoapConfiguration {
@Value("???")                  // based on 2 properties
private String wsUrl;
}
I would like to avoid complicated hierarchy of abstract configuration classes *only* based on `@Profile`. Moreover, I need to keep to keep *both* variables (mock and non-mock) in a common propery file. 
Is there a nice way that is both readable and maintainable?
</details>
# 答案1
**得分**: 1
你可以在构造函数中设置`wsUrl`。这不是非常优雅的解决方案,但它可以工作。
将`Environment` bean注入到你的`SoapConfiguration`中,然后检查是否激活了`mock`配置文件。
代码示例:
```java
@Configuration
public class SoapConfiguration {
    private final String wsUrl;
    public SoapConfiguration(Environment environment) {
        if (Arrays.asList(environment.getActiveProfiles()).contains("mock")) {
            this.wsUrl = environment.getProperty("ws.mock");
        } else {
            this.wsUrl = environment.getProperty("ws.endpoint");
        }
    }
}
英文:
You can set wsUrl in constructor. It's not so elegant solution but it works.
Inject Environment bean to your SoapConfiguration and check is mock profile active.<br>
Code example:
@Configuration
public class SoapConfiguration {
    private final String wsUrl;
    public SoapConfiguration(Environment environment) {
        if (Arrays.asList(environment.getActiveProfiles()).contains("mock")) {
            this.wsUrl = environment.getProperty("ws.mock");
        } else {
            this.wsUrl = environment.getProperty("ws.endpoint");
        }
    }
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论