Atrybuty @Value z application.properties nie są populowane wartościami

0

Cześć,

mam klasę:

@Service
@RequiredArgsConstructor
@Slf4j
public class Service { 
  @Value("${Wartosc_taka}")
  private String wartoscTaka;
  
  @Value("${Wartosc_itaka}")
  private String wartoscItaka;
}

I sa null ciagle. Wyciagam te wartosci z application.properties. application.properties jest w prawidlowym miejscu, nazwy tez sie zgadzaja w application Wartosc_taka=wartosc
Wartosc_itaka=wartosc

A caly czas rzuca nullami, nie wyciaga ich, nie widzi. Jako komponent klasa tez jest oznaczona, już nie wiem co robić:(

0

Problem pewnie wynika z lomboka - jakiej wersji używasz? Spróbuj zrobić tradycyjnie, przez konstruktor.

2

To co mówi dargenn. Wyrzuć lomboka z klasy i zacznie działać. Z tego co pamiętam gdy tak robisz (masz required args constructor) to wstrzykiwanie odbywa się przez konstruktor, a adnotacje z pól nie są propagowane na parametry konstruktora.

3

Opcja alternatywna, bo @Grzyboo podał właśnie jedno rozwiązanie

  1. Wywal lomboka.

  2. Wywal plik application.properties (a przynajmniej te wartości z niego).

  3. Wywal adnotacje @Value

  4. Wstaw pole jako
    private final String wartoscTaka = "jaką chciałeś";

  5. Ciesz się z programu, który działa, jak będziesz chciał zmienić wartość pola wartoscTaka to możesz to zrobić w pliku .java.
    Mało znana ciekawostka: pliki .java można edytować, często tymi samymi edytorami co pliki .properties (!!!)

0

Zaśmiane z punktu 5, ale jednak edytowanie propertiesów i późniejszy redeploy (albo nawet brak, jeżeli mamy dynamiczne propertiesy) w przypadku np. feature flag jest nieporównywalnie szybsze niż ponowne budowanie projektu i odpalanie całego pipeline. Oczywiście w przypadku komercyjnych aplikacji, w domowych zastosowaniach to jeden grzyb.

1

@dargenn: w absolutnej większości aplikacji, które kojarze - edytowanie propertiesów oznaczało odpalanie całego pipeline i całą biurokrację z release branchami, tagami itp. I zupełnie to rozumiem, naprawde nie wiadomo czasem co powiedzieć, jak po iluś godzinach przeglądania logów z produkcji, analizy totalnie absurdalnego buga, odkrywasz, że admini mówiąc nie ruszaliśmy properties nieco minęli się z prawdą.

1

A to swoją drogą. Propertiesy są strasznie nadużywane i w prawie każdym przypadku też wolę konfigurować w kodzie a nie yamlu.

1

Coż odkąd weszły dockery i tomcat przestałbyć popularny nie widziałem żeby ktoś zmieniał propertiesy na produkcji. Co innego zmienne środowiskowe, ale nawet nie wiem czy springowe @Value ogarnia zmienne środowiskowe.

0

Zamiast Wartosc_taka=wartosc zacznij od myprop=wartosc, jesli to nie dziala, to problem jest gdzies indziej.
Jesli dziala, to usun _ (zastąp - ?) oraz nie zaczynaj od wielkiej litery.

Coś tam było z camelcasem z propertiesami, między Spring Bootem 1, a 2. ;)

2

załaduj z import org.springframework.beans.factory.annotation.Value; a nie z import lombok.Value;

1

@stanley123: lombok nie ma tu nic do rzeczy. Można w Springu mieszać rodzaje wstrzyknięć i nie jest to problem dla springa, a dla programisty.

Po zerowe, która wersja springa i czy korzystasz ze spring boota?

Po pierwsze sprawdź, czy masz prawidłowy import. To, co pisał @hzmzp, mogłeś pomieszać importy i jest problem, a lombokowy @Value też przyjmuje parametr, więc nic się nie wysypuje.
Po drugie, dodaj do konfiguracji:

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

Jeżeli nie korzystasz ze Spring Boota, to prawdopodobnie nie korzystasz też z bibliotek, które konfigurują tego beana i trzeba to zrobić samodzielnie.

1

@KamilAdam: Oczywiście, że ogarnia :). Jak masz w propertisie org.dupa.zmienna to jak dodasz zmienna ORG_DUPA_ZMIENNA to ci ładnie nadpisze, albo możesz wrzucic jsona SPRING_APPLICATION_JSON z cała paczką do zmiennych środowiskowych.

@jarekr000000: Jak ogarniacie różne configi pomiędzy tenantami ?

1
Schadoow napisał(a):

@jarekr000000: Jak ogarniacie różne configi pomiędzy tenantami ?

Na szczęście nie mam teraz projektów gdzie muszę ogarniać konfigurację między tenantami.
Ale byłem w takiej firmie, gdzie norma to było:

  • osobny projekt w git:
    • w środku pliki properties
    • czasami (rzadko) dodatkowy kod (kilka klas)
    • depends od projektu bazowego

Zmiana propertiesów to zmiana w git + deploy.
Okazjonalne problemy, bo admini po raz kolejny podmienili sobie sami coś w properties (bezpośrednio na serwerze), bo im się wydawało, że są złe wartości :-)
Najgorsze, że takie zmiany bezpośrednio na serwerach nie przechodziły przez git więc w razie problemów nie zawsze można było złapać kto i kiedy eksperymentował.

I w tej sytuacji zamiast propertiesów na java sprawdziłaby sie dobrze. (ale nie przeforsowałem tego, a jedynie udało mi się zredukować liczbę rzeczy w properties, w niektórych aplikacjach - bo jak wszyscy mają tą samą wartość, to po co konfigurować).

2
Schadoow napisał(a):

@jarekr000000: Jak ogarniacie różne configi pomiędzy tenantami ?

Ta sama paczka, różna konfiguracja https://12factor.net/config . Najlepiej, żeby apka konsumowała envy, bo są najprostsze i chcąc nie chcąc i tak aplikacja ma do nich dostęp

2

@slsy To jest oczywiste chodziło mi o to, że wyciaganie przez VALUE daje ci tą zajebistość. że envy mogą być podane

  • przez plik xyz.properties na środowisku i spring sam robi merga
  • jako argumenty
  • jako zmienne środowiskowe
  • JNDI lub Java system properties

i nie musiałem ruszać ani jednej linijki kodu.

0
Schadoow napisał(a):

daje ci tą zajebistość. że envy mogą być podane

No nie wiem, ta zajebistość sprowadza się do tego, że muszę sprawdzić wszystkie te miejsca, żeby być pewny co mi wpływa na konfigurację. Kiedyś robiłem patcha do jakiejś korpo apki, która definiowała konfigurację na pierdyliard sposobów. Moja pierwsza mysł była taka wtf, nie ma opcji, żeby to się kiedyś nie zjebało i faktycznie po jakiejś tam zmianie wysypałą się produkcja, bo jedna z wielu super opcji na czytanie konfigu tj. otwieranie pliku z konfiguracją w osobnym wątku co jakiś czas spowodawała, że wyciekały handlery plików ze względu na bug w kodzie.

Wiadomo, że Spring też chce robić wszystko najlepiej jak się da, przez co czasami można się zgubić w możliwościach i nieprzemyślanych konsekwencjach, których normalnie by nie było

0

@slsy: Ale otwieranie plików z konfiguracja w osobnym wątku to był wasz wewnętrzny mechanizm. A nie springowy feature "external configuration".

0

Btw zamiast @Value o wiele lepsze jest @ConfigurationProperties - raz, że bardziej obiektowo podejście (tak tak wiem, żadna zaleta), ale dwa, że automatycznie się odświeży w przypadku późniejszego przejścia na Config-server.

1

@Schadoow: Kontynuując wątek poboczny - czemu czasem lepiej trzymać dane w kodzie - właśnie uświadomiłem sobie, że mnóstwo konfiguracji, która normalnie robiona by była np. yamlami (kubernetes) trzymamy w kodzie... (pulumi, dhall itp wynalazki). Więc poszliśmy krok dalej - kod generuje konfigi, dla softu, który z jakichś powodów konfigów potrzebuje.
Chociaż tak po prawdzie w przypadku kubernetesa te yamle to nie tyle konfig (bo wcale kubernetesa nie konfigurują) co po prostu api.

Co też nie oznacza, że z różnych względów nie mamy czasem ręcznych plików konfiguracyjnych - czasem mamy, bo jakiś soft, biblioteka potrzebuje i nie chciało nam się tego przerabiać, a w zeszłym tygodniu nawet wyszło, że możemy chcieć mieć JEDEN parametr konfiguracyjny.

0
Grzyboo napisał(a):

A to swoją drogą. Propertiesy są strasznie nadużywane i w prawie każdym przypadku też wolę konfigurować w kodzie a nie yamlu.

Jak rozumiem to później można nadpisać zmiennymi środowiskowymi?
Co wtedy trzymasz w kodzie jako defaulty? Wartości takie żeby apka się odpaliła lokalnie, czy wartości dla środowiska deweloperskiego (albo jakiegokolwiek innego)?
Czy mówisz tylko o wartościach, dla których z góry wiadomo, że jest znikoma szansa, że będą się różniły pomiędzy środowiskami?

0
some_ONE napisał(a):

Co wtedy trzymasz w kodzie jako defaulty? Wartości takie żeby apka się odpaliła lokalnie, czy wartości dla środowiska deweloperskiego (albo jakiegokolwiek innego)?

To akurat proste - trzymamy wartości takie, żeby odpaliła się na każdym z tych środowisk. Przecież nie muszą się różnić.

0
jarekr000000 napisał(a):

To akurat proste - trzymamy wartości takie, żeby odpaliła się na każdym z tych środowisk. Przecież nie muszą się różnić.

To przecież o tym właśnie wspomniałem :P
Jak to wartości które się nie zmieniają to ok, nie ma sensu ich pakować do configów.

1
some_ONE napisał(a):

Jak to wartości które się nie zmieniają to ok, nie ma sensu ich pakować do configów.

Też trzeba do tego podejść różnie w zależności od firmy i projektu. W jednej firmie zmiana kodu + redeploy mikroserwisu może być kwestią 10 minut, w korpo monolicie może wymagać odpalenia całego procesu zmiany na prodzie i wydania nowej wersji aplikacji, co nagle trwa wiele dni. Także takie springowe @Value w dobrym miejscu może czasem uratować tyłek.

0

Zawsze można zrobić reload propertiesow 'online'. Wygląda całkiem prosto :) .Mainstream przyszłości.

"@RefreshScope works (technically) on an @Configuration class, but it might lead to surprising behavior. For example, it does not mean that all the @Beans defined in that class are themselves in @RefreshScope. Specifically, anything that depends on those beans cannot rely on them being updated when a refresh is initiated, unless it is itself in @RefreshScope. In that case, it is rebuilt on a refresh and its dependencies are re-injected. At that point, they are re-initialized from the refreshed @Configuration)." https://cloud.spring.io/spring-cloud-static/Greenwich.SR2/multi/multi__spring_cloud_context_application_context_services.html

1 użytkowników online, w tym zalogowanych: 0, gości: 1