Spring Boot ve birden çok harici yapılandırma dosyası


125

Sınıf yolundan yüklemek istediğim birden çok özellik dosyam var. Altında /src/main/resourcesbir parçası olan bir varsayılan küme vardır myapp.jar. Benim springcontextbeklediği dosyaları üzerinde sınıf olmak. yani

<util:properties id="Job1Props"
    location="classpath:job1.properties"></util:properties>

<util:properties id="Job2Props"
    location="classpath:job2.properties"></util:properties>

Ayrıca bu özellikleri harici bir küme ile geçersiz kılma seçeneğine de ihtiyacım var. İçinde harici bir yapılandırma klasörüm var cwd. İlkbahar önyükleme belgesine göre yapılandırma klasörü sınıf yolunda olmalıdır. Ancak, yalnızca applicaiton.propertiesoradan veya config'deki tüm özellikleri geçersiz kılıp kılmayacağı doc'tan açık değildir .

Test ettiğimde, yalnızca application.propertiesalınıyor ve geri kalan mülkler hala toplanıyor /src/main/resources. Bunları virgülle ayrılmış liste olarak sağlamayı denedim, spring.config.locationancak varsayılan küme hala geçersiz kılınmıyor.

Birden çok harici yapılandırma dosyasının varsayılanları geçersiz kılmasını nasıl sağlayabilirim?

Geçici çözüm olarak şu anda app.config.locationkomut satırı aracılığıyla sağladığım (uygulamaya özgü özelliği) kullandım. yani

java -jar myapp.jar app.config.location=file:./config

ve benim değişti applicationcontextTo

<util:properties id="Job2Props"
    location="{app.config.location}/job2.properties"></util:properties>

Uygulamayı yüklerken dosya ve sınıf yolu arasında bu şekilde ayrım yapıyorum.
DÜZENLEMELER:

//psuedo code

if (StringUtils.isBlank(app.config.location)) {
            System.setProperty(APP_CONFIG_LOCATION, "classpath:");
}

Yukarıdaki geçici çözümü kullanmamayı ve dosya için olduğu gibi, sınıf yolundaki tüm harici yapılandırma dosyalarını yayın geçersiz kılmasını gerçekten istiyorum application.properties.


4
Her application.propertieszaman yüklenir, spring.config.locationdosyalar için kontrol edilen (yani a ile bittiği zaman) ek yapılandırma konumları ekleyebilirsiniz, /ancak buraya yüklenecek dosyaları işaret eden virgülle ayrılmış bir liste koyarsanız. Bu aynı zamanda Bahar Boot Başvuru Kılavuzu'nda açıklanmıştır burada
M. Deinum

Yanıtlar:


156

Spring Boot kullanılırken, özellikler aşağıdaki sırayla yüklenir ( Spring Boot başvuru kılavuzunda Haricileştirilmiş Yapılandırma'ya bakın ).

  1. Komut satırı argümanları.
  2. Java Sistem özellikleri (System.getProperties ()).
  3. İşletim sistemi ortam değişkenleri.
  4. Java'dan JNDI öznitelikleri: comp / env
  5. Yalnızca rasgele özelliklere sahip bir RandomValuePropertySource. *.
  6. Paketli jar'inizin dışındaki uygulama özellikleri (YAML ve profil varyantları dahil uygulama özellikleri).
  7. Jar'ınızın içinde paketlenmiş uygulama özellikleri (YAML ve profil varyantlarını içeren uygulama özellikleri).
  8. @Configuration sınıflarınızdaki @PropertySource ek açıklamaları.
  9. Varsayılan özellikler (SpringApplication.setDefaultProperties kullanılarak belirtilir).

Özellikleri çözümlerken (yani @Value("${myprop}")çözümleme ters sırada yapılır (9 ile başlayarak).

Farklı dosyalar eklemek için spring.config.location, özellik dosyalarının virgülle ayrılmış listesini veya dosya konumunu (dizinler) alan özellikleri kullanabilirsiniz .

-Dspring.config.location=your/config/dir/

Yukarıdaki, application.propertiesdosyalar için başvurulacak bir dizin ekleyecektir .

-Dspring.config.location=classpath:job1.properties,classpath:job2.properties

Bu, 2 özellik dosyasını yüklenen dosyalara ekleyecektir.

Varsayılan yapılandırma dosyaları ve konumları, ek olarak belirtilenlerden önce yüklenir, spring.config.locationyani ikincisi her zaman öncekilerde ayarlanan özellikleri geçersiz kılar. ( Spring Boot Başvuru Kılavuzunun bu bölümüne de bakın ).

Eğer spring.config.location(dosyalar aksine) dizinleri içerir onlar / bitmeli (ve oluşturulan adlarla eklenecektir spring.config.nameyüklenmeden önce). Varsayılan arama yolu classpath:,classpath:/config,file:,file:config/, değerine bakılmaksızın her zaman kullanılır spring.config.location. Bu şekilde, uygulamanız için varsayılan değerleri application.properties(veya seçtiğiniz başka bir temel adı) ayarlayabilir ve varsayılanları spring.config.namekoruyarak çalışma zamanında farklı bir dosya ile geçersiz kılabilirsiniz.

GÜNCELLEME: spring.config.location davranışı artık varsayılanı eklemek yerine varsayılanı geçersiz kılıyor. Varsayılanları korumak için spring.config.additional-location kullanmanız gerekir. Bu, 1.x'ten 2.x'e bir davranış değişikliğidir.


2
Teşekkürler, ancak bu ref belgesini zaten okudum ve aşağıdaki kafa karıştırıcı "-Dspring.config.location = sizin / config / dir / Yukarıdakiler application.properties dosyaları için başvurulacak bir dizin ekleyecek." Application.properties dosyalarının anlamı nedir? Bu sadece bir dosyadır. Her durumda, sonunda "/" olan tüm dizini alabiliyorsa, her birini virgülle ayrılmış liste olarak belirtmem gerekmiyor.
Gönderimde

Belgede belirtildiği gibi, application.propertiesve için diğer varsayılan konumlar gibi seçilecektir application-[env].properties. Diğer mülk dosyalarını hesaba katmaz. Bu aynı zamanda başvuru kılavuzunda da belirtilmiştir (bağlantının götürdüğü bölümde ve başvuru kılavuzundan alıntı).
M.Deinum

1
Evet ama bana mantıklı gelmeyen şey bu .. neden sınıf yolu üzerindeki bir dizinden tüm dizin yerine yalnızca bir tür dosya düşünelim. Sizi yalnızca bir özellik dosyası kullanmaya zorlar ki bu iyi bir imo değildir. Tomcat'te olduğu gibi, common.loader'ı sınıf yoluna belirli bir dizini (ve içindeki her şeyi) yerleştirecek şekilde yapılandırabilirim, neden sınıf yükleyicinin önyükleme yapamaması onu destekleyebilir.
2014

3
Belgelerden alıntı yapmak yardımcı olmaz. Dokümantasyon net olsaydı (yeterli mi? Özellikle ihtiyaç duyulan şekilde?), O zaman soru gerekli olmazdı. Örneğin, bu durumda, nasıl etkileşimde bulunduklarını zaten bilen insanlara muhtemelen açık görünse de, nasıl config.locationve config.namesetkileşimde bulunduğu gerçekten net değildir . Belgelere bir şey eklemek için cevabınızı güncelleyebilir misiniz ?
Narfanator

13
spring.config.locationŞimdi davranışı varsayılanı eklemek yerine varsayılanı geçersiz kıldığından, bu güncellenmelidir. spring.config.additional-locationVarsayılanları korumak için kullanmanız gerekir . Bu, 1.x'ten 2.x'e bir davranış değişikliğidir.
Robin

32

Spring boot ile spring.config.location çalışır, sadece virgülle ayrılmış özellik dosyaları sağlar.

aşağıdaki koda bakın

@PropertySource(ignoreResourceNotFound=true,value="classpath:jdbc-${spring.profiles.active}.properties")
public class DBConfig{

     @Value("${jdbc.host}")
        private String jdbcHostName;
     }
}

jdbc.properties dosyasının varsayılan sürümünü uygulamanın içine koyabilirsiniz. Harici versiyonlar buna göre ayarlanabilir.

java -jar target/myapp.jar --spring.config.location=classpath:file:///C:/Apps/springtest/jdbc.properties,classpath:file:///C:/Apps/springtest/jdbc-dev.properties

Spring.profiles.active özelliği kullanılarak ayarlanan profil değerine bağlı olarak, jdbc.host'un değeri alınacaktır. Yani ne zaman (Windows'ta)

set spring.profiles.active=dev

jdbc.host, jdbc-dev.properties'ten değer alacaktır.

için

set spring.profiles.active=default

jdbc.host, jdbc.properties'ten değer alacaktır.


İlk kod bloklarının işe yarayacağına inanmıyorum. Kendimi bu konuda sıkıştırdığımı ve bu cevabı takip ettiğimi biliyorum . İyi bir açıklama için yanıt olarak atıfta bulunulan jira.springsource.org/browse/SPR-8539 adresine bakın .
Sowka

27

Spring boot 1.X ve Spring Boot 2.X, aynı seçenekleri ve davranışları sağlamaz. Externalized Configuration .

M. Deinum'un çok iyi cevabı Spring Boot 1 özelliklerine atıfta bulunuyor.
Spring Boot 2'yi burada güncelleyeceğim.

Çevre özellikleri kaynakları ve sırası

Spring Boot 2 PropertySource, değerlerin makul şekilde geçersiz kılınmasına izin vermek için tasarlanmış çok özel bir sıra kullanır . Özellikler aşağıdaki sırayla değerlendirilir:

  • Ana dizininizdeki Devtools global ayarlar özellikleri (devtools etkinken ~ / .spring-boot-devtools.properties).

  • @TestPropertySource testlerinizle ilgili ek açıklamalar.

  • @SpringBootTest#propertiestestlerinizdeki açıklama özelliği. Komut satırı argümanları.

  • Özellikleri SPRING_APPLICATION_JSON(bir ortam değişkenine veya sistem özelliğine gömülü satır içi JSON).

  • ServletConfig init parametreleri.

  • ServletContext init parametreleri.

  • JNDI öznitelikleri java:comp/env.

  • Java Sistem özellikleri ( System.getProperties()).

  • İşletim sistemi ortam değişkenleri.

  • Bir RandomValuePropertySourcetek rastgele özellikleri vardır. *.

  • Paketlenmiş kavanozunuzun ( application-{profile}.propertiesve YAML varyantlarının) dışındaki profile özgü uygulama özellikleri .

  • application-{profile}.propertiesJar'ınızın ( ve YAML varyantlarının) içinde paketlenmiş profile özgü uygulama özellikleri .

  • Paketlenmiş kavanozunuzun ( application.propertiesve YAML varyantlarının) dışındaki uygulama özellikleri .

  • application.propertiesJar'ınızın ( ve YAML varyantlarının) içinde paketlenmiş uygulama özellikleri .

  • @PropertySource@Configurationsınıflarınızda ek açıklamalar . Varsayılan özellikler (ayar ile belirtilir SpringApplication.setDefaultProperties).

Harici özellik dosyalarını belirtmek için bu seçenekler ilginizi çekmelidir:

  • Paketlenmiş kavanozunuzun ( application-{profile}.propertiesve YAML varyantlarının) dışındaki profile özgü uygulama özellikleri .

  • Paketlenmiş kavanozunuzun ( application.propertiesve YAML varyantlarının) dışındaki uygulama özellikleri .

  • @PropertySource@Configurationsınıflarınızda ek açıklamalar . Varsayılan özellikler (ayar ile belirtilir SpringApplication.setDefaultProperties).

Bu 3 seçenekten sadece birini kullanabilir veya ihtiyacınıza göre kombinleyebilirsiniz.
Örneğin, çok basit durumlar için yalnızca profile özgü özellikleri kullanmak yeterlidir, ancak diğer durumlarda hem profile özgü özellikleri, hem varsayılan özellikleri hem de@PropertySource .

Application.properties dosyaları için varsayılan konumlar

Hakkında application.propertiesvarsayılan Bahar yükleri onları ve aşağıdaki sırayla bunlardan ortamda özelliklerini eklemek tarafından dosyalar (ve varyant),:

  • Mevcut dizinin A / config alt dizini

  • Mevcut dizin

  • Bir sınıf yolu / yapılandırma paketi

  • Sınıf yolu kökü

Daha yüksek öncelikler böylece anlamıyla şunlardır:
classpath:/,classpath:/config/,file:./,file:./config/.

Özellikler dosyaları belirli adlarla nasıl kullanılır?

Varsayılan konumlar her zaman yeterli değildir: varsayılan dosya adı ( application.properties) gibi varsayılan konumlar uygun olmayabilir. Ayrıca, OP sorusunda olduğu gibi, application.properties(ve varyant) dışında birden çok yapılandırma dosyası belirtmeniz gerekebilir .
Yanispring.config.name yeterli olmayacak.

Bu durumda, spring.config.locationortam özelliğini (dizin konumlarının veya dosya yollarının virgülle ayrılmış bir listesidir) kullanarak açık bir konum sağlamalısınız .
Dosya adları kalıbı konusunda özgür olmak için, dizinler listesi yerine dosya yolları listesini tercih edin.
Örneğin şunu beğen:

java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

Bu yol, sadece klasörü belirtmenin en ayrıntılı yoludur, ancak aynı zamanda yapılandırma dosyalarımızı çok ince bir şekilde belirtmenin ve etkin bir şekilde kullanılan özellikleri açık bir şekilde belgelemenin yoludur.

spring.config.location artık eklemek yerine varsayılan konumları değiştiriyor

Spring Boot 1 ile spring.config.locationargüman, Spring ortamında belirtilen konumları ekler.
Ancak Spring Boot 2'den, spring.config.locationSpring tarafından kullanılan varsayılan konumları , belgelerde belirtildiği gibi Spring ortamındaki belirtilen konumlarla değiştirir .

Özel yapılandırma konumları kullanılarak yapılandırıldığında spring.config.location, varsayılan konumların yerini alırlar. Örneğin, spring.config.locationdeğeri ile konfigüre edilir classpath:/custom-config/, file:./custom-config/arama düzeni şu hale gelir:

  1. file:./custom-config/

  2. classpath:custom-config/

spring.config.locationartık herhangi bir application.propertiesdosyanın açıkça belirtilmesi gerektiğinden emin olmanın bir yoludur . Dosyaları
paketlemesi gerekmeyen uber JAR'lar için bu application.propertiesoldukça hoş.

spring.config.locationSpring Boot 2'yi kullanırken eski davranışını korumak için , belgelerde belirtildiği gibi konumları eklemek spring.config.additional-locationyerine yeni özelliği kullanabilirsiniz :spring.config.location

Alternatif olarak, özel yapılandırma konumları kullanılarak yapılandırıldığında spring.config.additional-location, varsayılan konumlara ek olarak kullanılırlar.


Uygulamada

Öyleyse, OP sorusundaki gibi, belirtilecek 2 harici özellikler dosyanız ve uber jar'e 1 özellikler dosyası dahil edildiğini varsayalım.

Yalnızca belirttiğiniz yapılandırma dosyalarını kullanmak için:

-Dspring.config.location=classpath:/job1.properties,classpath:/job2.properties,classpath:/applications.properties   

Varsayılan konumlarda bunlara yapılandırma dosyaları eklemek için:

-Dspring.config.additional-location=classpath:/job1.properties,classpath:/job2.properties

classpath:/applications.properties son örnekte gerekli değildir, çünkü varsayılan konumlar buna sahiptir ve bu varsayılan konumlar burada üzerine yazılmaz, ancak genişletilir.


Cevabınız bir şey dışında gerçekten tamdır: "sınıf yolu: /job1.properties" belirtirseniz, Spring harici yapılandırma job1.properties'i diskte nerede bulacaktır? Harici özellikleri içeren dizininizi buradaki sınıf yoluna nasıl eklediniz?
Tristan

@Tristan, temelde, yay application.propertiestüm parametrelerle birini ve ${file_name}.propertieskısmi tanımlı özellik kümeleriyle çoklu okuyabilir . Bu nedenle, @PropertySourcedosyalara başka güçlü bağlantılar kullanıyorsanız, başka harici dosya oluşturabilir ve bu özellikleri geçersiz kılabilirsiniz (Örn: kimden classpath:file.properties).
Mister_Jesus

23

PropertyPlaceholderConfigurer'a bir göz atın, açıklamadan daha açık olduğunu düşünüyorum.

Örneğin

@Configuration
public class PropertiesConfiguration {


    @Bean
    public PropertyPlaceholderConfigurer properties() {
        final PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
//        ppc.setIgnoreUnresolvablePlaceholders(true);
        ppc.setIgnoreResourceNotFound(true);

        final List<Resource> resourceLst = new ArrayList<Resource>();

        resourceLst.add(new ClassPathResource("myapp_base.properties"));
        resourceLst.add(new FileSystemResource("/etc/myapp/overriding.propertie"));
        resourceLst.add(new ClassPathResource("myapp_test.properties"));
        resourceLst.add(new ClassPathResource("myapp_developer_overrides.properties")); // for Developer debugging.

        ppc.setLocations(resourceLst.toArray(new Resource[]{}));

        return ppc;
    }

Bu cevap için çok teşekkür ederim. Temel XML dosyası olmadan farklı şeyler için benzer XML yapılandırmalarına sahip bir projede aynısını nasıl başarabileceğimi bana bildirir misiniz? Yukarıdaki cevabınız, ek açıklama tabanlı başka bir projede bana yardımcı oldu. Bunun için tekrar teşekkürler.
Chetan

8

Bu, yaylı önyükleme kullanan basit bir yaklaşımdır

TestClass.java

@Configuration
@Profile("one")
@PropertySource("file:/{selected location}/app.properties")
public class TestClass {

    @Autowired
    Environment env;

    @Bean
    public boolean test() {
        System.out.println(env.getProperty("test.one"));
        return true;
    }
}

app.properties sizin bağlam, seçilen konuma

test.one = 1234

senin bahar çizme uygulaması

@SpringBootApplication

public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(testApplication.class, args);
    }
}

ve önceden tanımlanmış application.properties bağlamı

spring.profiles.active = one

Sadece spring.profiles.active ayarlayarak istediğiniz kadar konfigürasyon sınıfı yazabilir ve bunları etkinleştirebilir / devre dışı bırakabilirsiniz. = profil adı / adları {virgülle ayrılmış olarak}

Gördüğünüz gibi bahar botu harika, sadece alışmak için bir ara ihtiyaç duyuyor, tarlalarınızda da @ Değer kullanabileceğinizden bahsetmeye değer

@Value("${test.one}")
String str;

7

Ben de aynı sorunu yaşadım. Spring Boot application.properties algılamasına benzer şekilde, başlangıçta bir dahili yapılandırma dosyasının üzerine harici bir dosya ile yazma yeteneğine sahip olmak istedim. Benim durumumda, uygulamalarımın kullanıcılarının depolandığı bir user.properties dosyası.

Gereksinimlerim:

Dosyayı aşağıdaki konumlardan yükleyin (bu sırayla)

  1. Sınıf yolu
  2. Geçerli dizinin bir / config alt dizini.
  3. Mevcut dizin
  4. Başlangıçta bir komut satırı parametresi tarafından verilen dizinden veya dosya konumundan

Aşağıdaki çözümü buldum:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.util.Properties;

import static java.util.Arrays.stream;

@Configuration
public class PropertiesConfig {

    private static final Logger LOG = LoggerFactory.getLogger(PropertiesConfig.class);

    private final static String PROPERTIES_FILENAME = "user.properties";

    @Value("${properties.location:}")
    private String propertiesLocation;

    @Bean
    Properties userProperties() throws IOException {
        final Resource[] possiblePropertiesResources = {
                new ClassPathResource(PROPERTIES_FILENAME),
                new PathResource("config/" + PROPERTIES_FILENAME),
                new PathResource(PROPERTIES_FILENAME),
                new PathResource(getCustomPath())
        };
        // Find the last existing properties location to emulate spring boot application.properties discovery
        final Resource propertiesResource = stream(possiblePropertiesResources)
                .filter(Resource::exists)
                .reduce((previous, current) -> current)
                .get();
        final Properties userProperties = new Properties();

        userProperties.load(propertiesResource.getInputStream());

        LOG.info("Using {} as user resource", propertiesResource);

        return userProperties;
    }

    private String getCustomPath() {
        return propertiesLocation.endsWith(".properties") ? propertiesLocation : propertiesLocation + PROPERTIES_FILENAME;
    }

}

Artık uygulama sınıf yolu kaynağını kullanıyor, ancak verilen diğer konumlarda da bir kaynak olup olmadığını kontrol ediyor. Var olan son kaynak seçilecek ve kullanılacaktır. Teknemi yüzen bir özellik konumunu kullanmak için java -jar myapp.jar --properties.location = / directory / myproperties.properties ile uygulamamı başlatabiliyorum.

Burada önemli bir ayrıntı: Özellik ayarlanmadığında hataları önlemek için @ Değer ek açıklamasında properties.location için varsayılan değer olarak boş bir Dize kullanın.

Properties.location için kural şudur: Properties.location olarak bir özellikler dosyasına giden bir dizin veya yol kullanın.

Yalnızca belirli özellikleri geçersiz kılmak istiyorsanız, setIgnoreResourceNotFound (true) değerine sahip bir PropertiesFactoryBean, konum olarak ayarlanan kaynak dizisi ile kullanılabilir.

Eminim bu çözüm birden fazla dosyayı işleyecek şekilde genişletilebilir ...

DÜZENLE

Burada birden fazla dosya için çözümüm :) Daha önce olduğu gibi, bu bir PropertiesFactoryBean ile birleştirilebilir.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.util.Map;
import java.util.Properties;

import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toMap;

@Configuration
class PropertiesConfig {

    private final static Logger LOG = LoggerFactory.getLogger(PropertiesConfig.class);
    private final static String[] PROPERTIES_FILENAMES = {"job1.properties", "job2.properties", "job3.properties"};

    @Value("${properties.location:}")
    private String propertiesLocation;

    @Bean
    Map<String, Properties> myProperties() {
        return stream(PROPERTIES_FILENAMES)
                .collect(toMap(filename -> filename, this::loadProperties));
    }

    private Properties loadProperties(final String filename) {
        final Resource[] possiblePropertiesResources = {
                new ClassPathResource(filename),
                new PathResource("config/" + filename),
                new PathResource(filename),
                new PathResource(getCustomPath(filename))
        };
        final Resource resource = stream(possiblePropertiesResources)
                .filter(Resource::exists)
                .reduce((previous, current) -> current)
                .get();
        final Properties properties = new Properties();

        try {
            properties.load(resource.getInputStream());
        } catch(final IOException exception) {
            throw new RuntimeException(exception);
        }

        LOG.info("Using {} as user resource", resource);

        return properties;
    }

    private String getCustomPath(final String filename) {
        return propertiesLocation.endsWith(".properties") ? propertiesLocation : propertiesLocation + filename;
    }

}

güzel bir çözüm. Şu java8 yapıları gibi! her neyse bunu kullanamıyorum çünkü birden fazla Özellik fasulyesine ihtiyacım var. DÜZENLEMELERİMİ görürseniz, geçici çözümüm kullanım durumum için oldukça benzer ve temizdir.
nir

Birden fazla dosya için bir sürüm yayınladım, sadece eksiksizlik için;)
mxsb

6

Spring boot, farklı ortamlar için yazmak üzere farklı profiller yazmamızı sağlar, örneğin üretim, qa ve yerel ortamlar için ayrı özellik dosyalarımız olabilir.

yerel makineme göre yapılandırmalar içeren application-local.properties dosyası

spring.profiles.active=local

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=users
spring.data.mongodb.username=humble_freak
spring.data.mongodb.password=freakone

spring.rabbitmq.host=localhost
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.port=5672

rabbitmq.publish=true

Benzer şekilde, application-prod.properties ve application-qa.properties'i istediğimiz kadar özellik dosyası yazabiliriz.

sonra uygulamayı farklı ortamlar için başlatmak üzere bazı komut dosyaları yazın, örneğin

mvn spring-boot:run -Drun.profiles=local
mvn spring-boot:run -Drun.profiles=qa
mvn spring-boot:run -Drun.profiles=prod

5

Buna benzer bir sorun yaşadım ve sonunda sebebini buldum: application.properties dosyası yanlış sahiplik ve rwx niteliklerine sahipti. Dolayısıyla, tomcat başladığında application.properties dosyası doğru konumdaydı, ancak başka bir kullanıcıya aitti:

$ chmod 766 application.properties

$ chown tomcat application.properties

Sanırım benzer bir sorunum var. Tomcat'i opt klasörüne yükledim. Başvuru dosyanızı nereye koydunuz? Klasör özniteliklerini de değiştirmeli miyim?
anakin59490

3

@Mxsb çözümünün, birden çok dosyayı tanımlamamıza izin veren değiştirilmiş bir sürümü ve benim durumumda bunlar yml dosyaları.

Application-dev.yml dosyama, içinde -dev.yml olan tüm yml'leri enjekte etmeme izin veren bu yapılandırmayı ekledim. Bu, belirli dosyaların bir listesi de olabilir. "Sınıf yolu: /test/test.yml,classpath: /test2/test.yml"

application:
  properties:
    locations: "classpath*:/**/*-dev.yml"

Bu, bir özellik haritası almanıza yardımcı olur.

@Configuration

public class PropertiesConfig {

private final static Logger LOG = LoggerFactory.getLogger(PropertiesConfig.class);

@Value("${application.properties.locations}")
private String[] locations;

@Autowired
private ResourceLoader rl;

@Bean
Map<String, Properties> myProperties() {
    return stream(locations)
            .collect(toMap(filename -> filename, this::loadProperties));
}

private Properties loadProperties(final String filename) {

    YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
    try {
        final Resource[] possiblePropertiesResources = ResourcePatternUtils.getResourcePatternResolver(rl).getResources(filename);
        final Properties properties = new Properties();
        stream(possiblePropertiesResources)
                .filter(Resource::exists)
                .map(resource1 -> {
                    try {
                        return loader.load(resource1.getFilename(), resource1);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }).flatMap(l -> l.stream())
                .forEach(propertySource -> {
                    Map source = ((MapPropertySource) propertySource).getSource();
                    properties.putAll(source);
                });

        return properties;
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
}

Ancak, benim durumumda olduğu gibi, her profil için yml dosyalarını bölmek ve onları yüklemek ve fasulye başlatmadan önce bunu doğrudan yay konfigürasyonuna enjekte etmek istedim.

config
    - application.yml
    - application-dev.yml
    - application-prod.yml
management
    - management-dev.yml
    - management-prod.yml

... kaptın bu işi

Bileşen biraz farklı

@Component
public class PropertiesConfigurer extends     PropertySourcesPlaceholderConfigurer
    implements EnvironmentAware, InitializingBean {

private final static Logger LOG = LoggerFactory.getLogger(PropertiesConfigurer.class);

private String[] locations;

@Autowired
private ResourceLoader rl;
private Environment environment;

@Override
public void setEnvironment(Environment environment) {
    // save off Environment for later use
    this.environment = environment;
    super.setEnvironment(environment);
}

@Override
public void afterPropertiesSet() throws Exception {
    // Copy property sources to Environment
    MutablePropertySources envPropSources = ((ConfigurableEnvironment) environment).getPropertySources();
    envPropSources.forEach(propertySource -> {
        if (propertySource.containsProperty("application.properties.locations")) {
            locations = ((String) propertySource.getProperty("application.properties.locations")).split(",");
            stream(locations).forEach(filename -> loadProperties(filename).forEach(source ->{
                envPropSources.addFirst(source);
            }));
        }
    });
}


private List<PropertySource> loadProperties(final String filename) {
    YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
    try {
        final Resource[] possiblePropertiesResources = ResourcePatternUtils.getResourcePatternResolver(rl).getResources(filename);
        final Properties properties = new Properties();
        return stream(possiblePropertiesResources)
                .filter(Resource::exists)
                .map(resource1 -> {
                    try {
                        return loader.load(resource1.getFilename(), resource1);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }).flatMap(l -> l.stream())
                .collect(Collectors.toList());
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

}


3

Application.properties dosyanızda belirtilen değerleri geçersiz kılmak istiyorsanız, uygulamanızı çalıştırırken etkin profilinizi değiştirebilir ve profil için bir uygulama özellikleri dosyası oluşturabilirsiniz. Öyleyse, örneğin, "geçersiz kılma" etkin profilini belirleyelim ve ardından, / tmp altında "application-override.properties" adlı yeni uygulama özellikleri dosyanızı oluşturduğunuzu varsayarak, çalıştırabilirsiniz.

java -jar yourApp.jar --spring.profiles.active="override" --spring.config.location="file:/tmp/,classpath:/" 

Spring.config.location altında belirtilen değerler ters sırada değerlendirilir. Yani, benim örneğimde, önce classpat, ardından dosya değeri değerlendirilir.

Jar dosyası ve "application-override.properties" dosyası geçerli dizindeyse, aslında basitçe

java -jar yourApp.jar --spring.profiles.active="override"

Spring Boot sizin için özellikler dosyasını bulacağından


1
Spring'e "geçersiz kılma" profilini aktif profiliniz olarak kullanmasını söyleyecektir; gerçekten application.yml veya application.properties dosyasında belirtilen değeri
aşacaktır

o sayesinde güzel bir gezi oldu @acaruci, ben doğru sürer, sonra yalnızca uygulamaya profile.yml koymak benim durumumda herhangi yapılandırma dosyası .ymal veya .properties için klasörün içinde bakacağız
Ahmed Salem

0

Bunu, izlenecek faydalı bir model olarak buldum:

@RunWith(SpringRunner)
@SpringBootTest(classes = [ TestConfiguration, MyApplication ],
        properties = [
                "spring.config.name=application-MyTest_LowerImportance,application-MyTest_MostImportant"
                ,"debug=true", "trace=true"
        ]
)

Burada "application-MyTest_LowerImportance.yml" ve ayrıca "application-MyTest_MostImportant.yml" kullanmak için "application.yml" kullanımını geçersiz kılıyoruz
(Spring ayrıca .properties dosyalarını arayacaktır)

Ayrıca, ayrı bir satırda hata ayıklama ve izleme ayarları da ekstra bonus olarak dahildir, böylece gerekirse bunları yorumlayabilirsiniz;]

Spring, yüklediği tüm dosyaların ve yüklemeye çalıştığı dosyaların adlarını dökeceğinden, hata ayıklama / izleme inanılmaz derecede kullanışlıdır.
Çalışma zamanında konsolda bunun gibi satırlar göreceksiniz:

TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant.properties' (file:./config/application-MyTest_MostImportant.properties) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant.xml' (file:./config/application-MyTest_MostImportant.xml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant.yml' (file:./config/application-MyTest_MostImportant.yml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant.yaml' (file:./config/application-MyTest_MostImportant.yaml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_LowerImportance.properties' (file:./config/application-MyTest_LowerImportance.properties) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_LowerImportance.xml' (file:./config/application-MyTest_LowerImportance.xml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_LowerImportance.yml' (file:./config/application-MyTest_LowerImportance.yml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_LowerImportance.yaml' (file:./config/application-MyTest_LowerImportance.yaml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_MostImportant.properties' (file:./application-MyTest_MostImportant.properties) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_MostImportant.xml' (file:./application-MyTest_MostImportant.xml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_MostImportant.yml' (file:./application-MyTest_MostImportant.yml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_MostImportant.yaml' (file:./application-MyTest_MostImportant.yaml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_LowerImportance.properties' (file:./application-MyTest_LowerImportance.properties) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_LowerImportance.xml' (file:./application-MyTest_LowerImportance.xml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_LowerImportance.yml' (file:./application-MyTest_LowerImportance.yml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_LowerImportance.yaml' (file:./application-MyTest_LowerImportance.yaml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_MostImportant.properties' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_MostImportant.xml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_MostImportant.yml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_MostImportant.yaml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.properties' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.xml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.yml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.yaml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_MostImportant.properties' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_MostImportant.xml' resource not found
DEBUG 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Loaded config file 'file:/Users/xxx/dev/myproject/target/test-classes/application-MyTest_MostImportant.yml' (classpath:/application-MyTest_MostImportant.yml)
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_MostImportant.yaml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_LowerImportance.properties' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_LowerImportance.xml' resource not found
DEBUG 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Loaded config file 'file:/Users/xxx/dev/myproject/target/test-classes/application-MyTest_LowerImportance.yml' (classpath:/application-MyTest_LowerImportance.yml)
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_LowerImportance.yaml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant-test.properties' (file:./config/application-MyTest_MostImportant-test.properties) resource not found

-1

Bunu anlamaya çalışırken birçok sorunla karşılaştım. İşte kurulumum

Geliştirici Ortamı: Windows 10, Java: 1.8.0_25, Spring Boot: 2.0.3.RELEASE, Spring: 5.0.7.RELEASE

Bulduğum şey, baharın "Yapılandırma için mantıklı varsayılanlar" konseptine bağlı kaldığı. Bunun anlamı, tüm mülkiyet dosyalarınızı savaş dosyanızın bir parçası olarak almanız gerektiğidir. Oraya girdikten sonra, harici özellik dosyalarına işaret etmek için "--spring.config.additional-location" komut satırı özelliğini kullanarak bunları geçersiz kılabilirsiniz. Ancak, özellik dosyaları orijinal savaş dosyasının bir parçası değilse bu ÇALIŞMAZ.

Demo kodu: https://github.com/gselvara/spring-boot-property-demo/tree/master

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.