首页 文章

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

提问于
浏览
29

我有来自外部配置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

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

Spring-batch道具同样如此:

database.driver=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost/mydv
database.username=root
database.password=root

7 回答

  • 36

    您可以在生命周期侦听器中添加其他属性源,以响应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));
      }
    }
    

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

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

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

  • 1

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

    我希望在启动时以编程方式设置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);
        }
    }
    
  • 12
  • 1

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

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(Application.class)
                  .properties("propertyKey=propertyValue");
    }
    
  • 0

    从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);
            }
        }
    }
    
  • 0

    在META-INF文件夹下,准确创建此文件夹和文件:spring> batch> override> data-source-context.xml,并在xml文件中确保覆盖您想要的参数:

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${loader.jdbc.driver}" />
        <property name="url" value="${loader.jdbc.url}" />
        <property name="username" value="${loader.jdbc.username}" />
        <property name="password" value="${loader.jdbc.password}" />
    </bean>
    
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    

    或者在xml文件中使用这样的jndi来访问外部配置文件,如catalina.properties

    <jee:jndi-lookup id="dataSource"
        jndi-name="java:comp/env/jdbc/loader-batch-dataSource" lookup-on-startup="true"
        resource-ref="true" cache="true" />
    
  • 23

    如果必须,可以通过编程方式覆盖application.properties .

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

相关问题