web-dev-qa-db-ger.com

So überschreiben Sie Spring-Boot application.properties programmgesteuert

Ich habe jdbc-Eigenschaftendateien, die ich von einem externen Konfigurationswebdienst nehme. Im Frühjahr ist es einfach, diese zu application.properties hinzuzufügen, um mysql-Requisiten festzulegen:

spring.datasource.url=jdbc:mysql://localhost/mydb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

Wie kann ich diese programmtechnisch in meiner App überschreiben?

gleiches gilt für Spring-Batch-Requisiten:

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

Sie können einem Lifecycle-Listener zusätzliche Eigenschaftenquellen hinzufügen, die auf das ApplicationEnvironmentPrepared-Ereignis reagieren.

Etwas in der Art von:

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

Dann registrieren Sie die Klasse in src/main/resources/META-INF/spring.factories:

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

Für mich hat dies funktioniert, aber Sie sind in Bezug auf die derzeit verfügbaren Funktionen begrenzt, da sich die Startphase der Anwendung noch in einem relativ frühen Stadium befindet. Sie müssten einen Weg finden, um die gewünschten Werte zu erhalten, ohne sich auf eine andere Feder zu verlassen Bohnen etc.

45
Lukas Hinsch

Nur um diesem Thread eine andere Option als Referenz zu geben, als ich anfing, nach einer Antwort für meine Anforderung zu suchen, stand dies ganz oben auf der Suchliste, deckte aber meinen Anwendungsfall nicht ab.

Ich habe versucht, die Eigenschaft spring boot beim Start programmgesteuert festzulegen, ohne jedoch mit den verschiedenen von spring unterstützten XML/Config-Dateien arbeiten zu müssen.

Am einfachsten ist es, die Eigenschaften zum Zeitpunkt der Definition der SpringApplication festzulegen. Im folgenden Beispiel wird der Tomcat-Port auf 9999 festgelegt.

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

Seit Spring Boot 1.3 steht hierfür EnvironmentPostProcessor zur Verfügung. Erstellen Sie eine Unterklasse davon und registrieren Sie sich in META-INF/spring.factories. Ein gutes Beispiel ist hier:

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

18
Peter Szanto

Ab Spring Boot 2.0.X können Sie einzelne Eigenschaften (z. B. in einem Komponententest) mithilfe einer Kombination aus einem benutzerdefinierten ApplicationContextInitializer und der Annotation ContextConfiguration dynamisch überschreiben.

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

Mit dieser Methode können Sie in Ihrer Konfiguration Standardeigenschaften festlegen.

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

Auf diese Weise können Sie die application.properties bei Bedarf programmgesteuert überschreiben.

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

Erstellen Sie unter META-INF genau diese Ordner und Datei: spring> batch> override> data-source-context.xml und stellen Sie in Ihrer XML-Datei sicher, dass Sie die gewünschten Parameter wie folgt überschreiben:

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

oder verwenden Sie ein JNDI wie dieses in der XML-Datei, um auf Ihre externe Konfigurationsdatei wie catalina.properties zuzugreifen

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