【问题标题】:Changing Spring Boot Properties Programmatically以编程方式更改 Spring Boot 属性
【发布时间】:2016-05-22 08:49:56
【问题描述】:

我正在尝试为使用@RefreshScope 的应用程序编写测试。我想添加一个实际更改属性并断言应用程序响应正确的测试。我已经想出了如何触发刷新(在RefreshScope 中自动装配并调用refresh(...)),但我还没有想出修改属性的方法。如果可能的话,我想直接写入属性源(而不是处理文件),但我不知道去哪里找。

更新

这是我正在寻找的示例:

public class SomeClassWithAProperty {
    @Value{"my.property"}
    private String myProperty;

    public String getMyProperty() { ... }
}

public class SomeOtherBean {
    public SomeOtherBean(SomeClassWithAProperty classWithProp) { ... }

    public String getGreeting() {
        return "Hello " + classWithProp.getMyProperty() + "!";
    }
}

@Configuration
public class ConfigClass {
    @Bean
    @RefreshScope
    SomeClassWithAProperty someClassWithAProperty() { ...}

    @Bean
    SomeOtherBean someOtherBean() {
        return new SomeOtherBean(someClassWithAProperty());
    }
}

public class MyAppIT {
    private static final DEFAULT_MY_PROP_VALUE = "World";

    @Autowired
    public SomeOtherBean otherBean;

    @Autowired
    public RefreshScope refreshScope;

    @Test
    public void testRefresh() {
        assertEquals("Hello World!", otherBean.getGreeting());

        [DO SOMETHING HERE TO CHANGE my.property TO "Mars"]
        refreshScope.refreshAll();

        assertEquals("Hello Mars!", otherBean.getGreeting());
    }
}

【问题讨论】:

    标签: java spring spring-cloud


    【解决方案1】:

    应用程序中使用的属性必须是带有@Value 注释的变量。这些变量必须属于由 Spring 管理的类,例如带有 @Component 注解的类。

    如果您想更改属性文件的值,您可以设置不同的配置文件并为每个配置文件拥有不同的 .properties 文件。

    我们应该注意,这些文件是静态的并且只加载一次,因此以编程方式更改它们有点超出预期用途的范围。但是,您可以在 spring boot 应用程序中设置一个简单的 REST 端点,该端点修改主机文件系统上的文件(很可能在您正在部署的 jar 文件中),然后在原始 spring boot 应用程序上调用 Refresh。

    【讨论】:

    • 感谢您的评论!我想我可能不清楚,所以我更新了问题以显示我在寻找什么。可能可以使用配置文件将 Cloud Config 指向属性文件并编辑该文件,但我更愿意以某种方式托管模拟 Cloud Config 服务或以其他方式直接拼接到加载过程中,以避免写出测试期间的属性文件。
    • 他们根本不必是@Value。可以在@ConfigurationProperties或者直接通过Environment使用。
    • 也许我应该指定这是一种方法。
    【解决方案2】:

    您可以这样做(我假设您错误地省略了示例顶部的 JUnit 注释,所以我会为您重新添加它们):

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = Application.class)
    public class MyAppIT {
    
        @Autowired
        public ConfigurableEnvironment environment;
    
        @Autowired
        public SomeOtherBean otherBean;
    
        @Autowired
        public RefreshScope refreshScope;
    
        @Test
        public void testRefresh() {
            assertEquals("Hello World!", otherBean.getGreeting());
    
            EnvironmentTestUtils.addEnvironment(environment, "my.property=Mars");
            refreshScope.refreshAll();
    
            assertEquals("Hello Mars!", otherBean.getGreeting());
        }
    }
    

    但您并没有真正测试您的代码,只是 Spring Cloud 的刷新范围功能(已经针对此类行为进行了广泛测试)。

    我很确定您也可以从现有的刷新范围测试中得到这个。

    【讨论】:

    • 感谢您为我指明了正确的方向——我最终使用了一个非常相似的解决方案,涉及 MockPropertySource。虽然我同意这已在 Spring Cloud 中进行了全面测试,但我想确保我们的代码正确使用它。 (在这种情况下,测试没有通过,因为@Config 类正在注入值(通过@Value),而不是在刷新范围的 bean 中包含值。因为我们的一些开发人员在刷新范围的文档中遇到了问题,我需要想出一个解决方案来测试他们的代码,以确保它正确使用 Spring。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2017-02-27
    • 2021-09-03
    • 1970-01-01
    • 2016-11-17
    • 2017-06-06
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多