Spring Boot - Konfiguracja

W projektach opartych o Spring Boot korzystamy z mechanizmu konfiguracyjnego, który jest podstawowym elementem bazowej wersji Springa (takiej, w której nie używamy Spring Boota). Konfiguracja jest więc zwyczajowo przechowywana w plikach o nazwach application.properties albo application.yml, znajdujących się w src/main/resources lub src/test/resources (dla testów) . Pliki te różnią się formatem przechowywania danych.

Pliki *.properties vs *.yml

Plik application.properties przechowuje dane w postaci powiązania klucz - wartość:
server.port=8080
server.session.timeout=600

spring.profiles.active=DEV
spring.http.multipart.max-file-size=3MB
Plik application.yml przechowuje dane w postaci hierarchicznej:
server:
    port: 8080
    session:
        timeout: 600

spring:
    profiles:
        active: DEV
    http:
        multipart:
            max-file-size: 3MB
Z założenia pliki w formacie YAML (yml) są bardziej "human readable" i tak też prezentuje się powyższy przykład. Nam jednak bardziej podoba się stara, kompaktowa wersja, w postaci pliku properties. Co kto lubi.

Niemniej trzeba zwrócić uwagę na to, że obecnie panuje moda na YAML-a i bardzo często konfiguracje w oficjalnych dokumentacjach (np. OAuth2 dla Google'a) przedstawiane są właśnie w tym formacie. Warto się z nim zaprzyjaźnić.

Profile w konfiguracji

Należy pamiętać, że pliki konfiguracyjne mogą być tworzone osobno dla każdego środowiska. Zatem jeśli mamy np. środowisko DEV i PROD, wówczas zwykle tworzymy taki zestaw plików:

application-DEV.properties
application-PROD.properties
application.properties

Dodatkowo warto jeszcze wprowadzić plik, który będzie używany w przypadku lokalnej konfiguracji na własnej maszynie dev.:

application-LOCAL.properties

Oczywiście takie pliki będą ładowane zgodnie z ustawionym profilem Springa.
Zatem, jeśli teraz na przykład ustawimy zmienną (argument JVM) podczas uruchamiania aplikacji:

-Dspring.profiles.active=DEV

wówczas zaczytana zostanie konfiguracja w kolejności z plików:

application-DEV.properties
application.properties

Więc najpierw plik dedykowany dla środowiska, a następnie plik ogólny. Jeśli plik dedykowany posiada ten sam klucz co plik ogólny, to wtedy ta wartość nadpisze wartość z pliku ogólnego. Jeśli w pliku dedykowanym mamy ustawioną własność server.port=8089, a w pliku ogólnym server.port=8080, to wówczas własność ta przyjmie wartość 8089.

Własność spring.profile.active

Aktywny profile (bądź profile) w Springu możemy ustawiać na kilka różnych sposobów:
  • Interfejs SpringBootServletInitializer lub bezpośrednio WebApplicationInitializer (rozszerza tego pierwszego):
    @Configuration
    public class Application implements SpringBootServletInitializer {
     
        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
      
            servletContext.setInitParameter("spring.profiles.active", "DEV");
        }
    }
    
  • Interfejs ConfigurableEnvironment - rzadko używany ze względu na mnogość innych bardziej popularnych opcji:
    @Autowired
    private ConfigurableEnvironment env;
    
    ...
    env.setActiveProfiles("DEV");
    
  • Argument maszyny wirtualnej (JVM) - w Eclipsach ustawiamy: Run As > Run Configurations... > Arguments > VM arguments...
    -Dspring.profiles.active=dev
    
    Może też być ustawiany z poziomu linii komend lub jako parametr podany w trakcie uruchomiania Tomcata.
  • Zmienna środowiskowa - zwracamy uwagę, że w tym przypadku zamiast kropek wstawiamy podkreślenia:
    export spring_profiles_active=DEV
    
  • Profil Mavena - w tym przypadku naszym celem będzie podmiana placeholdera (z małpą), który wcześniej musimy dodać do pliku application.properties - spring.profiles.active=@spring.profiles.active@:
    <profiles>
        <profile>
            <id>DEV</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <spring.profiles.active>DEV</spring.profiles.active>
            </properties>
        </profile>
        <profile>
            <id>PROD</id>
            <properties>
                <spring.profiles.active>PROD</spring.profiles.active>
            </properties>
        </profile>
    </profiles>
    
    Należy również pamiętać o włączeniu filtrowania zasobów (aby mogła się udać podmiana placeholdera):
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        ...
    </build>
    
W powyższych przykładach używaliśmy tylko jednego profilu, ale w ten sam sposób można ustawiać kilka profilów na raz. Na przykład możemy chcieć aby zaczytana została konfiguracja zarówno dla naszego środowiska lokalnego, jak i środowiska deweloperskiego:
-Dspring.profiles.active=LOCAL,DEV

Adnotacja @Profile

Korzystając z wyżej wymienionych profili możemy spowodować, że nasze klasy będą ładowane tylko dla określonego profilu. W tym celu wystarczy, że podczas tworzenia klasy użyjemy adnotacji @Profile:
@Service
@Profile({ "DEV" })
public class UserServiceImpl implements UserService {

    ...

}   
Uwzględniając to, że adnotacja przyjmuje tablicę stringów, możemy określić kilka profilów, dla których dana klasa ma być załadowana:
@Service
@Profile({ "DEV", "LOCAL" })
public class UserServiceImpl implements UserService {

    ...

}   

Podstawowe własności konfiguracyjne

Wracając do Spring Boota, spójrzmy teraz na subiektywną listę popularnych własności konfiguracyjnych wraz z opisami:

server.port - port HTTP, na którym ma być uruchomiony projekt Spring Boot
server.session.timeout - czas trwania sesji
server.ssl.enabled - flaga wskazująca czy połączenie powinno być szyfrowane
server.ssl.key-alias - alias dla klucza w ramach szyfrowania
server.ssl.key-store.timeout - miejsce przechowywania klucza
server.ssl.key-password - hasło do klucza
   
spring.profiles.active - nazwa aktywnego profilu Springa
spring.http.multipart.max-file-size - max. rozmiar pliku przesyłanego na serwer
   
spring.jpa.hibernate.ddl-auto - skrót do hibernate.hbm2ddl.auto, tryb automatycznej aktualizacji schematu bazy danych
spring.jpa.show-sql - flaga wskazująca czy SQL-e powinny być logowane
   
spring.h2.console.enabled - flaga wskazująca czy konsola bazy h2 ma być dostępna
spring.h2.console.path - ścieżka, pod którą konsola bazy h2 jest dostępna na serwerze
spring.h2.console.settings.web-allow-others - flaga wskazująca czy do konsoli bazy h2 można podłączyć się zdalnie
Oczywiście oryginalna lista własności konfiguracyjnych jest dużo, ale to naprawdę dużo dłuższa, niż ta przedstawiona w bieżącym rozdziale, dlatego zachęcamy do odwiedzenia linka podanego na dole strony, który prowadzi bezpośrednio do dokumentacji Springa zawierającej całą listę.
Nasza rekomendacja
Konfiguracja YAML jest bardzo popularna i powszechnie stosowana w projektach działających w architekturze mikrousług (microservices). Jakoś tak się dzieje, że w przypadku klasycznych aplikacji webowych częściej spotykamy konfiguracje oparte na plikach properties.

Nic nie stoi również na przeszkodzie, aby używać obu plików w jednocześnie. Wtedy część konfiguracji, która jest typowa dla YAML-a (np. OAuth2) może być przechowywana w pliku yml, a pozostała część w pliku properties. Podoba nam się takie podejście. Niemniej nie powinniśmy generalizować. Wszystko zależy w dużej mierze od ustaleń osób pracujących w projekcie, szczególnie jeśli jest to samoorganizujący się zespół scrumowy.

Używamy w StartAPPa


Wszystkie nasze kursy zawierają odpowiednio skonfigurowane pliki properties. Opisane własności konfiguracyjne zostały zebrane z modułów aplikacji. Dodatkowo w niektórych plikach używamy również nasze własne zmienne konfiguracyjne, np. ścieżki, w których są przechowywane zdjęcia (Formularz Zaawansowany), albo konfigurację konta pocztowego do wysyłania maili (Login & Reset).

Z profilów korzystamy, ale tylko aby lokalnie rozróżnić wersje klas między tymi, które są używane w ramach aplikacji dostępnej online a tymi, które są udostępniane w niezależnych modułach (do ściągnięcia). Wynika to z tego, że mając kilka mniejszych aplikacji złączonych w jedną, niektóre klasy muszą być przez nas wyłączone z użycia, aby nie duplikowały się ich funkcjonalności. Dotyczy to w szczególności klas konfiguracyjnych.
Linki
https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

Stale się rozwijamy, a więc bądź na bieżąco!
Na ten adres będziemy przesyłać informacje o ważniejszych aktualizacjach, a także o nowych materiałach pojawiających się na stronie.
Polub nas na Facebooku:
Nasi partnerzy:
Javappa to również profesjonalne usługi programistyczne oparte o technologie JAVA. Jeśli chesz nawiązać z nami kontakt w celu uzyskania doradztwa bądź stworzenia aplikacji webowej powinieneś poznać nasze doświadczenia.
Kliknij O nas .