如何以编程方式覆盖 Spring Boot application.properties?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29072628/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I override Spring Boot application.properties programmatically?
提问by rayman
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-service 中获取在 Spring Boot 中,为了设置 mysql props,将它们添加到 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
回答by Lukas Hinsch
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.
这对我有用,但是,由于在应用程序启动阶段还很早,因此此时您可以做的事情受到了一定的限制,您必须找到一种方法来获得所需的值,而无需依赖其他 spring豆类等
回答by Roger Thomas
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. The basic example below sets the tomcat port to 9999.
最简单的方法是在定义 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);
}
}
回答by Peter Szanto
Since spring boot 1.3 EnvironmentPostProcessoris available for this purpose. Create a subclass of it and register in META-INF/spring.factories A good example is here :
由于 spring boot 1.3 EnvironmentPostProcessor可用于此目的。创建它的子类并在 META-INF/spring.factories 中注册一个很好的例子是这里:
回答by Jason
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);
}
}
}
回答by Vadim Kirilchuk
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);
}
}
回答by Dimitri
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");
}
回答by idmitriev
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}
回答by Kishore Vanapalli
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);
}
回答by Shilan
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" />