如何以编程方式覆盖Spring-boot application.properties

ray*_*man 43 spring spring-batch spring-batch-admin spring-boot

我有来自外部配置web-service的jdbc属性文件在spring boot中为了设置mysql道具,将它们添加到application.properties很容易:

spring.datasource.url=jdbc:mysql://localhost/mydb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
Run Code Online (Sandbox Code Playgroud)

我怎么能在我的应用程序中重写那些程序?

Spring-batch道具同样如此:

database.driver=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost/mydv
database.username=root
database.password=root
Run Code Online (Sandbox Code Playgroud)

Luk*_*sch 48

您可以在生命周期侦听器中添加其他属性源,以响应ApplicationEnvironmentPrepared事件.

有点像:

public class DatabasePropertiesListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
  public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
    ConfigurableEnvironment environment = event.getEnvironment();
    Properties props = new Properties();
    props.put("spring.datasource.url", "<my value>");
    environment.getPropertySources().addFirst(new PropertiesPropertySource("myProps", props));
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在src/main/resources/META-INF/spring.factories中注册该类:

org.springframework.context.ApplicationListener=my.package.DatabasePropertiesListener
Run Code Online (Sandbox Code Playgroud)

这对我来说很有用,但是,你现在可以做些什么,因为它在应用程序启动阶段相当早,你必须找到一种方法来获得你需要的值而不依赖于其他弹簧豆子等

  • 正是我需要的.如果它对任何人有帮助,您可以使用'environment.getProperty("<prop-name>")'从application.properties中获取现有属性,并在代码中进一步使用它.我最终通过从我的属性文件中定义的整数填充spring.hornetq.embedded.queues属性来构建动态数量的hornetqueus. (4认同)

Rog*_*mas 26

只是为这个线程提供另一个选项以供参考,因为当我开始寻找我的要求的答案时,这在搜索列表中很高,但是没有涵盖我的用例.

我希望在启动时以编程方式设置spring boot属性,但不需要使用spring支持的不同XML/Config文件.

最简单的方法是在定义SpringApplication时设置属性.下面的基本示例将tomcat端口设置为9999.

@SpringBootApplication
public class Demo40Application{

    public static void main(String[] args){
        SpringApplication application = new SpringApplication(Demo40Application.class);

        Properties properties = new Properties();
        properties.put("server.port", 9999);
        application.setDefaultProperties(properties);

        application.run(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这不会覆盖内部属性,但是添加其他属性的好方法 (4认同)

Yon*_*nas 17

如果您出于测试目的需要这样做:从 spring-test 5.2.5 开始您可以使用@DynamicPropertySource

    @DynamicPropertySource
    static void setDynamicProperties(DynamicPropertyRegistry registry) {
        registry.add("some.property", () -> some.way().of(supplying).a(value) );
    }
Run Code Online (Sandbox Code Playgroud)

优先于几乎所有其他提供财产的方式。但该方法必须是静态的。


小智 9

从 Spring Boot 2.0.X 开始,您可以使用自定义 ApplicationContextInitializer 和 ContextConfiguration 注释的组合动态覆盖单个属性(例如,在单元测试中)。

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.PortTest.RandomPortInitailizer;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.support.TestPropertySourceUtils;
import org.springframework.util.SocketUtils;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(initializers = RandomPortInitializer.class)
public class PortTest {
    @Autowired
    private SomeService service;

    @Test
    public void testName() throws Exception {
        System.out.println(this.service);
        assertThat(this.service.toString()).containsOnlyDigits();
    }

    @Configuration
    static class MyConfig {

        @Bean
        public SomeService someService(@Value("${my.random.port}") int port) {
            return new SomeService(port);
        }
    }

    static class SomeService {
        private final int port;

        public SomeService(int port) {
            this.port = port;
        }

        @Override
        public String toString() {
            return String.valueOf(this.port);
        }
    }

    public static class RandomPortInitializer
            implements ApplicationContextInitializer<ConfigurableApplicationContext> {

        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            int randomPort = SocketUtils.findAvailableTcpPort();
            TestPropertySourceUtils.addInlinedPropertiesToEnvironment(applicationContext,
                    "my.random.port=" + randomPort);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Dim*_*tri 5

使用配置中的此方法,您可以设置默认属性。

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class)
              .properties("propertyKey=propertyValue");
}
Run Code Online (Sandbox Code Playgroud)


Vad*_*huk 5

如果您正在运行 Spring Boot 应用程序,这就是在启动期间设置属性的方法。

最简单的方法是在启动应用程序之前设置属性。

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Application.class);
        ConfigurableEnvironment env = new ConfigurableEnvironment();
        env.setActiveProfiles("whatever");

        Properties properties = new Properties();
        properties.put("server.port", 9999);
        env.getPropertySources()
            .addFirst(new PropertiesPropertySource("initProps", properties));

        application.setEnvironment(env);
        application.run(args);
    }
}
Run Code Online (Sandbox Code Playgroud)


idm*_*iev 5

It could be very simple:

@SpringBootApplication
public class SampleApplication {

  public static void main(String[] args) {
    new SpringApplicationBuilder(SampleApplication.class)
        .properties(props())
        .build()
        .run(args);
  }

  private static Properties props() {
    Properties properties = new Properties();
    properties.setProperty("MY_VAR", "IT WORKS");
    return properties;
  }
}
Run Code Online (Sandbox Code Playgroud)

application.yml

test:
  prop: ${MY_VAR:default_value}
Run Code Online (Sandbox Code Playgroud)