web-dev-qa-db-fra.com

Comment remplacer programme.properties de Spring-boot par programme

J'ai des fichiers de propriétés jdbc que je récupère du service Web de configuration externe. Au printemps, pour configurer les accessoires mysql, il est simple d'ajouter ceux-ci à 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

Comment pourrais-je remplacer ces programmes dans mon application?

il en va de même pour les accessoires Spring-batch:

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

Vous pouvez ajouter des sources de propriétés supplémentaires dans un écouteur de cycle de vie réagissant à l'événement ApplicationEnvironmentPrepared.

Quelque chose dans le genre de:

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

Enregistrez ensuite la classe dans src/main/resources/META-INF/spring.factories:

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

Cela a fonctionné pour moi, cependant, vous êtes en quelque sorte limité à ce que vous pouvez faire à ce stade car il est assez tôt dans la phase de démarrage de l'application, vous devez trouver un moyen d'obtenir les valeurs dont vous avez besoin sans compter sur d'autres sources. haricots etc.

45
Lukas Hinsch

Juste pour fournir une autre option à ce fil de discussion, car lorsque j'ai commencé à chercher une réponse à mon exigence, cela figurait en haut de la liste de recherche, mais ne couvrait pas mon cas d'utilisation.

Je cherchais à définir par programme la propriété spring boot au démarrage, mais sans qu'il soit nécessaire de travailler avec les différents fichiers XML/Config pris en charge par spring.

Le moyen le plus simple consiste à définir les propriétés au moment de la définition de SpringApplication. L'exemple de base ci-dessous définit le port Tomcat sur 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);
    }
}
26
Roger Thomas

Depuis le démarrage printanier 1.3 EnvironmentPostProcessor est disponible à cette fin. Créez-en une sous-classe et enregistrez-vous dans META-INF/spring.factories. Un bon exemple est ici:

https://github.com/spring-cloud/spring-cloud-sleuth/blob/48f3f9783f277a795d0210399f0ea09b7f1a4e71/spring-cloud-cloud-sleuth-core/salc/main/ /sleuth/autoconfig/TraceEnvironmentPostProcessor.Java

18
Peter Szanto

A partir de Spring Boot 2.0.X, vous pouvez remplacer dynamiquement des propriétés individuelles (par exemple, dans un test unitaire) en combinant un annuaire ApplicationContextInitializer personnalisé et l'annotation 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);
        }
    }
}
3
Jason

Avec cette méthode dans votre configuration, vous pouvez définir les propriétés par défaut.

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

Voici comment vous pouvez remplacer le programme application.properties par programmation si vous devez le faire.

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

Dans le dossier META-INF, créez exactement ce dossier et ce fichier: spring> batch> override> data-source-context.xml et dans votre fichier xml, veillez à remplacer les paramètres de votre choix:

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

ou utilisez un jndi comme celui-ci dans le fichier XML pour accéder à votre fichier de configuration externe comme 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" />
0
Shilan