![](/img/trans.png)
[英]How to override application.properties during production in Spring-Boot?
[英]How can I override Spring Boot application.properties programmatically?
我有 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
我怎么能在我的應用程序中覆蓋那些程序?
Spring-batch 道具也是如此:
database.driver=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost/mydv
database.username=root
database.password=root
您可以在對 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 引導屬性,但不需要使用 spring 支持的不同 XML/配置文件。
最簡單的方法是在定義 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);
}
}
由於 spring boot 1.3 EnvironmentPostProcessor可用於此目的。 創建它的子類並在 META-INF/spring.factories 中注冊一個很好的例子是這里:
從 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);
}
}
}
如果您正在運行 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);
}
}
這可能非常簡單:
@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;
}
}
應用程序.yml
test:
prop: ${MY_VAR:default_value}
如果您出於測試目的需要這樣做:從 spring-test 5.2.5 開始,您可以使用@DynamicPropertySource
:
@DynamicPropertySource
static void setDynamicProperties(DynamicPropertyRegistry registry) {
registry.add("some.property", () -> some.way().of(supplying).a(value) );
}
優先於幾乎所有其他提供屬性的方式。 該方法必須是靜態的。
在您的配置中使用此方法,您可以設置默認屬性。
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class)
.properties("propertyKey=propertyValue");
}
如果需要,您可以通過這種方式以編程方式覆蓋 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);
}
將字符串添加到您的應用程序 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);
}
}
在 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" />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.