简体   繁体   English

如何以编程方式覆盖 Spring Boot application.properties?

[英]How can I override Spring Boot application.properties programmatically?

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.properties:我有 jdbc 属性文件,我从外部配置 Web 服务中获取在 spring 引导中,为了设置 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

How could I override those programticlly in my app?我怎么能在我的应用程序中覆盖那些程序?

same goes for Spring-batch props: Spring-batch 道具也是如此:

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

You can add additional property sources in a lifecycle listener reacting to ApplicationEnvironmentPrepared event.您可以在对 ApplicationEnvironmentPrepared 事件做出反应的生命周期侦听器中添加其他属性源。

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:然后在 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.这对我有用,但是,由于在应用程序启动阶段还很早,您此时可以做的事情受到了一定的限制,您必须找到一种方法来获得所需的值,而无需依赖其他弹簧豆类等

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.我希望在启动时以编程方式设置 spring 引导属性,但不需要使用 spring 支持的不同 XML/配置文件。

The easiest way is to set the properties at the time the SpringApplication is defined.最简单的方法是在定义 SpringApplication 时设置属性。 The basic example below sets the tomcat port to 9999.下面的基本示例将 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);
    }
}

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

This is how you can set properties during startup if you are running spring boot application.如果您正在运行 Spring Boot 应用程序,这就是在启动期间设置属性的方法。

The easiest way is to set the properties before you even started an app.最简单的方法是在启动应用程序之前设置属性。

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

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应用程序.yml

test:
  prop: ${MY_VAR:default_value}

If you need to do this for testing purposes: since spring-test 5.2.5 you can use @DynamicPropertySource :如果您出于测试目的需要这样做:从 spring-test 5.2.5 开始,您可以使用@DynamicPropertySource

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

Takes precedence over pretty much all of the other ways of supplying properties.优先于几乎所有其他提供属性的方式。 The method must be static though.该方法必须是静态的。

With this Method in your configuration you can set default properties.在您的配置中使用此方法,您可以设置默认属性。

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

This is how you can override the application.properties programatically if you have to.如果需要,您可以通过这种方式以编程方式覆盖 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);

}

Add string to your Application class将字符串添加到您的应用程序 class

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        System.setProperty("spring.config.location",
                "file:///D:/SpringProjects/SpringBootApp/application.properties");

        SpringApplication.run(Application.class, args);
    }

}

Under META-INF folder create exactly this folders and file: spring>batch>override>data-source-context.xml and in your xml file make sure to override the paramters you want like this:在 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>

or use a jndi like this in the xml file to access your external configuration file like catalina.properties或者在 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" />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 Spring-Boot 的生产过程中覆盖 application.properties? - How to override application.properties during production in Spring-Boot? 如何在Spring Boot集成测试中覆盖application.properties? - How to override application.properties in Spring Boot integration test? 如何在Upstart中设置Spring Boot环境变量以覆盖application.properties? - How do I set Spring Boot environment variables in Upstart to override application.properties? 使用外部属性覆盖 spring-boot application.properties - Override spring-boot application.properties with external properties 如何阅读Spring Boot application.properties? - How to read Spring Boot application.properties? 如何在 application.properties 文件中覆盖 spring boot starter 的默认属性? - How to override spring boot starter's default properties in application.properties file? 覆盖application.properties以在Spring-boot应用程序中进行集成测试 - Override application.properties for integration tests in spring-boot app Spring 引导:尝试使用 EnvironmentPostProcessor 覆盖 application.properties - Spring Boot: Attempting to override application.properties using EnvironmentPostProcessor 如何在不使用 application.properties 的情况下在 Spring Boot 中创建 db2 连接? - How can I create a db2 connection in Spring boot without use application.properties? 用application.properties覆盖默认的Spring-Boot application.properties - Override default Spring-Boot application.properties with application.properties
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM