it-swarm.com.de

Spring-Boot-Multi-Modul-Eigenschaft zum Laden von Projekten

Ich habe eine Spring-Boot-Applikation als Multimodul-Projekt in maven. Die Struktur ist wie folgt:

Parent-Project
|--MainApplication
|--Module1
|--ModuleN

Im Projekt MainApplication gibt es die Methodenklasse main(), die mit @SpringBootApplication usw. kommentiert ist. Dieses Projekt hat wie immer eine Datei application.properties, die automatisch geladen wird. So kann ich mit der Annotation @Value auf die Werte zugreifen

@Value("${myapp.api-key}")
private String apiKey;

In meinem Module1 möchte ich auch eine Eigenschaftendatei (modul1.properties) verwenden, in der die Modulkonfiguration gespeichert ist. Auf diese Datei wird nur im Modul zugegriffen. Aber ich kann es nicht laden. Ich habe es mit @Configuration und @PropertySource probiert, aber kein Glück.

@Configuration
@PropertySource(value = "classpath:module1.properties")
public class ConfigClass {

Wie kann ich eine Eigenschaftendatei mit Spring-Boot laden und einfach auf die Werte zugreifen? Konnte keine gültige Lösung finden.

Meine Konfiguration  

@Configuration
@PropertySource(value = "classpath:tmdb.properties")
public class TMDbConfig {

    @Value("${moviedb.tmdb.api-key}")
    private String apiKey;

    public String getApiKey() {
        return apiKey;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

Aufruf der Config

@Component
public class TMDbWarper {

@Autowired
private TMDbConfig tmdbConfig;

private TmdbApi tmdbApi;

public TMDbWarper(){
    tmdbApi = new TmdbApi(tmdbConfig.getApiKey());
}

Ich erhalte eine NullPointerException im Konstruktor, wenn ich den Warper automatisch löse.

16
Daniel

Bei Feldeinspritzung:

Felder werden direkt nach der Konstruktion eines Beans eingefügt, bevor Konfigurationsmethoden aufgerufen werden. Ein solches Konfigurationsfeld muss nicht öffentlich sein. Siehe Automatisch verdrahtete Anmerkungen zur vollständigen Verwendung. Verwenden Sie die Konstruktorinjektion in diesem Fall wie folgt:

@Component
public class TMDbWarper {

    private TMDbConfig tmdbConfig;

    private TmdbApi tmdbApi;

    @Autowired
    public TMDbWarper(final TMDbConfig tmdbConfig){
            this.tmdbConfig = tmdbConfig;
            tmdbApi = new TmdbApi(tmdbConfig.getApiKey());
    }

(oder)

Verwenden Sie @PostConstruct, um wie folgt zu initialisieren:

@Component
public class TMDbWarper {

    @Autowired
    private TMDbConfig tmdbConfig;

    private TmdbApi tmdbApi;

    @PostConstruct
    public void init() {
        // any initialisation method
        tmdbConfig.getConfig();
    }
6
Subash J

Autowiring wird direkt nach der Erstellung des Objekts ausgeführt (nach Aufruf des Konstruktors über Reflektion). Daher wird NullPointerException in Ihrem Konstruktor erwartet, da das tmdbConfig-Feld beim Aufruf des Konstruktors null sein würde

Sie können dies beheben, indem Sie die @ PostConstruct-Callback-Methode wie unten gezeigt verwenden:

@Component
public class TMDbWarper {

    @Autowired
    private TMDbConfig tmdbConfig;

    private TmdbApi tmdbApi;

    public TMDbWarper() {

    }

    @PostConstruct
    public void init() {
        tmdbApi = new TmdbApi(tmdbConfig.getApiKey());
    }

    public TmdbApi getTmdbApi() {
        return this.tmdbApi;
    }
}

Der Rest Ihrer Konfiguration scheint mir richtig zu sein. 

Hoffe das hilft.

5
skadya

Hier ist ein Beispiel für ein Spring Boot-Multimodul, in dem Sie Eigenschaften in verschiedenen Modulen erhalten können ..__ Nehmen wir an, ich habe main application module, dataparse-module , datasave-module.

StartApp.Java in application module:

@SpringBootApplication
public class StartApp {

    public static void main(String[] args) {

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

Konfiguration im dataparse-Modul . ParseConfig.Java:

@Configuration
public class ParseConfig {
        @Bean
        public XmlParseService xmlParseService() {
            return new XmlParseService();
        }
}

XmlParseService.Java:

@Service
public class XmlParseService {...}

Konfiguration im datasave-Modul . SaveConfig.Java:

@Configuration
@EnableConfigurationProperties(ServiceProperties.class)
@Import(ParseConfig.class)//get beans from dataparse-module - in this case XmlParseService
public class SaveConfig {

    @Bean
    public SaveXmlService saveXmlService() {
        return new SaveXmlService();

    }

}

ServiceProperties.Java:

@ConfigurationProperties("datasave")
public class ServiceProperties {

    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

application.properties im Ordner datasave-module im Ordner resource/config:

datasave.message = Multi-Modul-Maven-Projekt! 

threads.xml.number = 5 

file.location.on.disk = D:\temp\registry

In datasave-module können Sie alle Ihre Eigenschaften entweder über @Value verwenden.

SaveXmlService.Java:

@Service
public class SaveXmlService {

    @Autowired
    XmlParseService xmlParseService;

    @Value("${file.location.on.disk: none}")
    private String fileLocation;

    @Value("${threads.xml.number: 3}")
    private int numberOfXmlThreads;

    ...
}

Oder über ServiceProperties:

Service.Java:

@Component
public class Service {

    @Autowired
    ServiceProperties serviceProperties;

    public String message() {

        return serviceProperties.getMessage();

    }
}
3
Kirill Ch

Ich hatte diese Situation zuvor und bemerkte, dass die Eigenschaftendatei nicht in das Glas kopiert wurde.

Ich habe folgendes gemacht, damit es funktioniert:

  1. Im Ressourcenordner habe ich ein eindeutiges Paket erstellt und dann meine Datei application.properties darin gespeichert. z. B. com/company/project

  2. In der Konfigurationsdatei, z. B. TMDBConfig.Java, habe ich auf den vollständigen Pfad meiner .properties-Datei verwiesen:

    @Configuration
    @PropertySource("classpath:/com/company/project/application.properties")
    public class AwsConfig
    

Bauen und ausführen, es funktioniert wie Magie.

1

Sie können die Verbindung automatisch abwickeln und die Eigenschaft Enviornment verwenden, um die Eigenschaft zu lesen

@Configuration
@PropertySource(value = "classpath:tmdb.properties")
public class TMDbConfig {

  @Autowired
  private Environment env;

  public String getApiKey() {
    return env.getRequiredProperty("moviedb.tmdb.api-key");
  }

}

Dies sollte gewährleisten, dass die Eigenschaft aus dem Kontext gelesen wird, wenn Sie die getApiKey()-Methode aufrufen, unabhängig davon, wann der @Value-Ausdruck von PropertySourcesPlaceholderConfigurer aufgelöst wird.

0
Karol Dowbecki