How can I override Spring Boot application.properties programmatically?

后端 未结 10 1605
失恋的感觉
失恋的感觉 2020-11-29 18:33

I have jdbc property files which I take from external configuration web-service In spring boot in order to set mysql props it\'s easy as adding those to application.properti

相关标签:
10条回答
  • 2020-11-29 18:58

    You can add additional property sources in a lifecycle listener reacting to ApplicationEnvironmentPrepared event.

    Something along the lines of:

    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));
      }
    }
    

    Then register the class in src/main/resources/META-INF/spring.factories:

    org.springframework.context.ApplicationListener=my.package.DatabasePropertiesListener
    

    This worked for me, however, you are sort of limited as to what you can do at this point as it's fairly early in the application startup phase, you'd have to find a way to get the values you need without relying on other spring beans etc.

    0 讨论(0)
  • 2020-11-29 19:01

    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;
      }
    }
    

    application.yml

    test:
      prop: ${MY_VAR:default_value}
    
    0 讨论(0)
  • 2020-11-29 19:02

    This is how you can override the application.properties programatically if you have to.

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Restdemo1Application.class);
        app.setAdditionalProfiles("dev"); 
        // overrides "application.properties" with  "application-dev.properties"
        app.run(args);
    
    }
    
    0 讨论(0)
  • 2020-11-29 19:04

    Just to provide another option to this thread for reference as when I started to look for an answer for my requirement this came high on the search list, but did not cover my use case.

    I was looking to programmatically set spring boot property at start up, but without the need to work with the different XML/Config files that spring supports.

    The easiest way is to set the properties at the time the SpringApplication is defined. The basic example below sets the tomcat port to 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);
        }
    }
    
    0 讨论(0)
  • 2020-11-29 19:07

    As of Spring Boot 2.0.X, you can dynamically override individual properties (for example, in a unit test) using a combination of a custom ApplicationContextInitializer and the ContextConfiguration annotation.

    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);
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-29 19:10

    Since spring boot 1.3 EnvironmentPostProcessor is available for this purpose. Create a subclass of it and register in META-INF/spring.factories A good example is here :

    https://github.com/spring-cloud/spring-cloud-sleuth/blob/48f3f9783f277a795d0210399f0ea09b7f1a4e71/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java

    0 讨论(0)
提交回复
热议问题