Czy ten Spring to na pewno jest taki bee?

Odpowiedz Nowy wątek
2019-03-12 09:25
eL
3

Cześć.
Od kilku lat pracuje jako java dev. Pamiętam jeszcze projekty w starszych wersjach Springa gdzie trzeba było konfigurować tone XMLi żeby wszystko chciało działać. Aktualnie Spring w mojej ocenie niesamowicie się zmienił i praca ze Spring Bootem + stackiem Springa jest bardziej przyjemna a community ogromne choć jak każda technologia ma ogrom zalet ale i też wad przez co nawet tutaj na forum często można spotkać opinie żeby szukać alternatyw. I super, bo to na pewno bardzo rozwojowe ale czy dobre w kontekście rozwijania projektów?

Jakiś czas temu chciałem napisać prototyp pewnej aplikacji i pomyślałem że bedzie to dobra okazja do nauki nowych technologi. Zamiast Springa postawiłem aplikację na alternatywnych technologiach, np.: Kotlin, Ktor (asynchroniczny serwer http), Kodein (IoC), JOOQ (dostęp do bazy danych).
Z jednej strony zauważyłem sporo zalet takiego podejścia. W przypadku JOOQ mam poczucie pełnej kontroli nad bazą danych (co w Spring Data czy w ogóle JPA nie zawsze było takie odczuwalne bo zawsze gdzieś ten element 'magi' w postaci wygenerowanych tabel czy zapytań pozostaje). Z drugiej jednak strony to co działało w Spring Data tutaj sprawia problemy, np część testów funkcyjnych uruchamiam na bazie H2 w pamięci. Problem w tym że w kodzie jak dodaje rekordy do bazy danych to potrzebuje je od razu zwrócić razem z id by dalej przetworzyć. Spring Data przy zapisie zawsze zwraca zapisaną encję a w jooq jest returning: https://www.jooq.org/doc/late[...]t-statement/insert-returning/
Niby spoko, też fajnie ale na H2 to nie działa, problem zauważony już od 2014 roku a nadal nie jest naprawiony: https://github.com/jOOQ/jOOQ/issues/3035
Efekt jest taki że testy padają i trzeba robić jakieś workaround'y.

Inna sprawa to pobieranie konfiguracji z plików yaml albo propierties. W Spring'u mamy @Value który wszystko robi za nas. Bez springa trzeba kombinować i ręcznie wszystko zaciągać - niby są biblioteki typu Snakeyaml i inne tego typu ale nie jest to już tak intuicyjne.

Generalnie przykładów mógłbym powielać więcej ale nie rozwodząc się już zbyt mocno przejdę do puenty.
Czy to nie jest trochę tak że Spring jak każdy inny framework ma swoje wady i zalety i pewne rzeczy może faktycznie robi dziwnie i z jednej strony możemy na niego narzekać ale prawda jest taka że nie ma aktualnie równie dobrej alternatywy?
Czy koszt wprowadzenia nowych technologii i zmaganie się z innymi problemami (które i tak przyjdą bo żadna technologia nie jest idealna) nie jest czasami większy?
Spring ma za sobą ogromne community, całkiem długą historię rozwoju, wypracowane dobre praktyki i mimo że też nie jest pozbawiony wad to na codzień produkcyjnie korzystamy właśnie z niego bo tak naprawdę porzucenie jego niewiele by zmieniło (zamienilibyśmy jedne problemy na inne)?

Gdzieś przeczytałem (nie potrafię teraz znaleźć) że "framework to zbiór kompromisów" - kelog 2019-03-13 21:26
@kelog: i to by się nawet zgadzało ;) - eL 2019-03-14 06:36

Pozostało 580 znaków

2019-03-15 14:09
0

Ciekaw jestem jak często wymienialiście framework. Ja pamiętam takie sytuacje ale w zasadzie zawsze (1 wyjątek) było to przy okazji przepisania systemu od nowa.
Zatem to dla mnie nie jest argument za wprowadzeniem dodatkowej komplikacji zwanej warstwą abstrakcji.
KISS i YAGNI - to jest najważniejsze :)

Pokaż pozostałe 3 komentarze
@magic_m: policz sobie ile masz max zależności @Autowired per klasa. (zależności na polach licz z wagą 2). Jak Ci gdzieś wychodzi więcej niż 5 to kod jest przegrany - utraciłeś kontrolę. - jarekr000000 2019-03-15 17:05
@jarekr000000: a jeśli nie mam wiecej niz 5 to mogę i jest ok? Ale jesli masz komentowac w stylu "tak" albo "kod jest przegrany" i tyle, to sobie już teraz odpuśćmy bo szkoda czasu - magic_m 2019-03-15 18:14
@jarekr000000: tutaj Twoj argument jest inwalidą z całym szacunkiem - to że wywalisz Autowired na konstruktorze nie spowoduje że nagle znikną nadmiarowe zależności. Ja korzystam ze Springa a nie pamiętam kiedy ostatni raz stworzyłem klase z więcej niż 4 czy 5 zależnościami w kodzie produkcyjnym. - scibi92 2019-03-17 00:52
@scibi92: w pewnym sensie masz rację, jakkolwiek ja takie 18-to kołowce to spotykam tylko w Springowych kodach. Po prostu nie ma kary. - jarekr000000 2019-03-17 08:47

Pozostało 580 znaków

2019-03-15 14:50
1

@magic_m: pisanie testów jest łatwiejsze (i są one szybsze) jak testujesz kod w samej javie niż jak testujesz kod+springa


:D
A kto zmusza Cię do testowania springa? I co to w ogóle znaczy? - magic_m 2019-03-15 14:54
Wybitnie irytujące jest czekanie w testach aż Spring załaduje te wszystkie swoje beany i ciul wie co on tam jeszcze robi przez te parę sekund (przy gołym projekcie oczywiście), jeśli unit testy w javie bez kontekstu Springa wykonują się na poziomie kilkunastu milisekund. - kkojot 2019-03-15 17:42
to chyba nie unit ale integracyjne. Poza tym można, jeśli jest taka potrzeba, wypełniać większość zależności ręcznie i mieć jeszcze profil "in-memory" z repozytoriami operującymi na danych w pamięci - wtedy aplikacja i testy startują błyskawicznie. To ciągle jest mocne użycie springa, bez warstw abstrakcji oddzielających od frameworku. - magic_m 2019-03-15 18:25
czyli to co opisujesz to własnie polega na oddzieleniu logiki i frameworka - danek 2019-03-15 22:58
@danek to co opisałem może i polega na oddzielaniu logiki, ale tylko w (częściowym) przejęciu odpowiedzialności za wstrzykiwanie zależności. Nie wyklucza używania innych cech frameworka. Zresztą to tylko jedna z opcji. Normalnie oparłbym się na prawdziwych unit testach (ze zmockowanymi zależnościami) a testy integracyjne ograniczył i odpalał rzadziej. W ten sposób mam szybkie testy. - magic_m 2019-03-18 17:08
@magic_m: jeszcze możesz wywalić mocki i dopiero będziesz miał szybkie testy :) - danek 2019-03-18 17:18

Pozostało 580 znaków

2019-03-15 20:45
0

Co by nie mowic to obecnie wszystko poza Springiem to troche folklor.

Jestem ciekaw tylko jak serverless i cloud wymusi pewne rzeczy np. https://quarkus.io/

edytowany 1x, ostatnio: karsa, 2019-03-15 21:21
Pokaż pozostałe 2 komentarze
tak, ciekawe to razem z graalvm itp. ale ciekaw jestem czy powstanie z takich ruchow jakis popularny konkurent ;) - karsa 2019-03-15 22:18
chociaz widzialem odpalanie springa na tym micronaut z graalvm gdzies - karsa 2019-03-15 22:18
@karsa: Raczej nie, Spring bije wszystkie dotychczasowe rozwiązania doświadczeniem, powstawał latami - Burdzi0 2019-03-15 22:19
Ale na pewno wymusi to na nich jakieś dostosowanie się i raczej tego się spodziewam - karsa 2019-03-15 22:53

Pozostało 580 znaków

2019-03-16 13:27
0

Abstrahując od dobrego lub złego Springa - czemu beany i aspekty są złe? @jarekr000000

Bo Jarek lubi singletony. - karsa 2019-03-16 15:22

Pozostało 580 znaków

2019-03-16 16:37
1

@Emdzej93 Bo zamiast stosować dobry design i poliformizm, bawisz się w technologie, które skanują Twoje klasy, modyfikują ich bytecode, polegają często na nieudokumentowanych częściach JDK. Wszystko w aspektach jest "stringly" typed. Jedna literówka w pointcut i leżysz.

Oczywiście wszystko ciężko testowalne. Bez Springa nie przetestujesz.

Jeszcze jakieś argumenty? :)


"Gdy się nie wie, co się robi, to się dzieją takie rzeczy, że się nie wie, co się dzieje"


edytowany 1x, ostatnio: nie100sowny, 2019-03-16 16:38

Pozostało 580 znaków

2019-03-16 16:47
0
nie100sowny napisał(a):

@Emdzej93 Bo zamiast stosować dobry design i poliformizm, bawisz się w technologie, które skanują Twoje klasy, modyfikują ich bytecode, polegają często na nieudokumentowanych częściach JDK. Wszystko w aspektach jest "stringly" typed. Jedna literówka w pointcut i leżysz.

Oczywiście wszystko ciężko testowalne. Bez Springa nie przetestujesz.

Jeszcze jakieś argumenty? :)

Ja nie chciałem zabrzmieć jak jakiś obrońca beanów i aspektów, tylko miałem nadzieje usłyszeć jakieś historię od bardziej doświadczonych kolegów którzy się przy nich sparzyli, bądź poczytać jakiś ciekawy artykuł na ten temat ;)

Pozostało 580 znaków

2019-03-16 17:23
0
nie100sowny napisał(a):

@Emdzej93 Bo zamiast stosować dobry design i poliformizm, bawisz się w technologie, które skanują Twoje klasy, modyfikują ich bytecode, polegają często na nieudokumentowanych częściach JDK. Wszystko w aspektach jest "stringly" typed. Jedna literówka w pointcut i leżysz.

Oczywiście wszystko ciężko testowalne. Bez Springa nie przetestujesz.

Jeszcze jakieś argumenty? :)

W jaki sposób korzystanie z beanów kłóci się z polimorfizmem? Zreszta własnie Spring ułatwia korzystanie z polimorfizmu bo możesz łatwo wstrzyknąc wszystkie implementnacje interfejsu.I jak ma się korzystanie z dobrego designu w sprzeczności z IoC? Chhyba że lubisz tracisz czas na ręczne rejestrowanie wszystkich zalezności. No to pozdro xD


Nie pomagam przez PM. Pytania zadaje się na forum.
Pokaż pozostałe 9 komentarzy
No właśnie @scibi92 jednak nie. Fakt, że aby nie powtarzać tego new to musze sobie stworzyć jakąś architekturę. Pech, że dawno cruda ze zwykłym repo nie robiłem, żeby mieć dobry przykład. Ale jak wrzucisz kawałek z masą new to mogę Ci zrobić refaktor (tylko muszą być testy). - jarekr000000 2019-03-17 08:50
No tak, będziesz miał pewno fasady itd ale nadal to będzie pewno spora liczba linijek :d - scibi92 2019-03-17 08:54
Wole takie linijki niż tyle samo linijek adnotacji albo konfiguracji beanów ._. - baant 2019-03-17 10:28
No ja potrzebuje dodać całą jedną @Component nad klasą :D I co najlepsze to rozwiązanie czyste, bo możesz wywalić Springa i dalej będzie działać tlyko musisz rejestrować zależności "z palca" :) - scibi92 2019-03-17 10:31
Jedno Twoje Component to jedno moje new.... i jak wywale Springa to nie musze rejestrowac z palca, bo juz to mam :) - baant 2019-03-17 10:34

Pozostało 580 znaków

2019-03-16 18:28
6

Co jest złego w beanach i aspektach?
Aspekty:
zamiast mieć kod sprawdzany kompilatorem to polegamy na runtimowym wbogacaniu kulturowym,
W efekcie wywala się dopiero na produkcji.
Do tego aspekty te są bardzo wrażliwe na pozornie całkiem nieistotne zmiany w kodzie:

  • zmieniamy metodę na private -> boom, aspekty wysiadają,
  • wywołujemy z tego samego beana metodę - > boom.
  • wywołujemy asynchronizczne - boom
    • dorzucamy (lub nie) jednego jara -> boom (i to dopiero na produkcji).
  • itd. (ale testy działają ),

Beany to jak dla mnie tesknota za BASICIem, gdzie wszystko było globalne. Fakt, że czasem niezłe skróty dzięki temu można było zrobić :-) Takie beany to w zasadzie singletony , które można wszędzie wstrzyknać olewając zupełnie architekturę i zdrowy rozsądek. Do tego jeszcze dochodzą beany typu JobScope, RequestScope przy których nawet zmienne globalne czasem bledną... Bo to global per thread, w efekcie śledzenie jest jeszcze bardziej utrudnione.

Wersja TL;DR .
Nie po to Wanda nie chciała BASICA, żeby nasze dzieci babrały się w runtimowej magii i wywalały kod na produkcji.


Bardzo lubie Singletony, dlatego robię po kilka instancji każdego.
edytowany 4x, ostatnio: jarekr000000, 2019-03-16 18:36
W obronie BASIC-a powiem, że pochwała dla globali występuje / występowała też w enterprajsowym COBOL-u i domowym PHP3. Za to nawet na Atari 8-bit w 1983 były już języki z lokalnymi zmiennymi - Action!. - vpiotr 2019-03-16 18:53
Jest jednak spora roznica miedzy beanem, ktory mozna wszedzie wstrzyknac a singletonem, ktorego mozna wszedzie uzyc bez wstrzykniecia (Singleton.getInstance() z dowolnego miejsca kodu). - magic_m 2019-03-18 17:17
@magic_m zgadzam się, że jest różnica. Tylko kolejna taka różnica jest między normalną klasą, a beanem który można wszędzie wstrzyknąć. - jarekr000000 2019-03-18 21:40

Pozostało 580 znaków

2019-03-16 19:57
0
scibi92 napisał(a):
nie100sowny napisał(a):

@Emdzej93 Bo zamiast stosować dobry design i poliformizm, bawisz się w technologie, które skanują Twoje klasy, modyfikują ich bytecode, polegają często na nieudokumentowanych częściach JDK. Wszystko w aspektach jest "stringly" typed. Jedna literówka w pointcut i leżysz.

Oczywiście wszystko ciężko testowalne. Bez Springa nie przetestujesz.

Jeszcze jakieś argumenty? :)

W jaki sposób korzystanie z beanów kłóci się z polimorfizmem? Zreszta własnie Spring ułatwia korzystanie z polimorfizmu bo możesz łatwo wstrzyknąc wszystkie implementnacje interfejsu.I jak ma się korzystanie z dobrego designu w sprzeczności z IoC? Chhyba że lubisz tracisz czas na ręczne rejestrowanie wszystkich zalezności. No to pozdro xD

Pisałem o aspektach...


"Gdy się nie wie, co się robi, to się dzieją takie rzeczy, że się nie wie, co się dzieje"


Pozostało 580 znaków

2019-03-16 20:53
0

Ja osobiście do pisania jakiś prototypów aplikacji czy MVP lubię użyć Spring Boota, bo wszystko od razu skonfigurowane itd. Do tego stosując podejście gdzie nie robisz każdej klasy beanem springowym tylko dzielisz sensownie projekt na moduły, gdzie w każdym jedynym beanem będzie klasa Fasady, czyli wejścia do modułu (poza springowymi implementacjami jakiś JpaRepository) możesz to łatwo testować w pamięci bez stawiania kontekstu. Testujesz sobie publiczne metody fasady (razem z corner casami), integracyjnie testujesz jedynie use casy (tylko te robiące Ci hajs). Dzięki temu możesz na testy powstrzykiwać jakieś InMemory implementacje repo na javowych kolekcjach (najlepiej Vavr) i swoje testy jednostkowe (testujesz fasady, więc zachowanie, a nie mokito) uruchamiasz bez Springa. W najlepszym wypadku masz konfigurację całej apki w pamięci. Problem zaczyna się jak chcesz mieć CQRS bo trzeba to jakoś obchodzić, no ale coś za coś.

W produkcyjnych projektach, jak robiłem w banku to faktycznie jaja z dynamic proxy czy thread local lub n+1 z JPA potrafią zrobić wtfy.

Sam kiedyś chciałem pisać aspekty, ale pomyśl sobie, że ktoś Twój kod potem czyta i chciałby go zrozumieć jak najszybciej. Beng !

edytowany 3x, ostatnio: Bambo, 2019-03-16 20:55
Pokaż pozostałe 13 komentarzy
Bambo - wtedy dla testów i inmemory robiłem to samo - command trzymałem w domenie, a query osobno w innym pakiecie, inMemory wyglądało tak, że była klasa w domenie, która implementowała package private command repo i publiczne repo query, a z tyłu siedziała ta sama hashmapa - hcubyc 2019-03-17 00:11
@hcubyc: masz gdzieś to na jakimś przykładzie na jakimś repo publicznym ? Albo masz chwilkę klepnąć prototyp ? - Bambo 2019-03-17 00:16
https://youtu.be/ILBX9fa9aJo?t=2015 tu Kuba pokazuje jak to wygląda od strony pakietów - BioRepository package-private, BioQueryRepository public. Potem w testach do pakietu 'domain' mozna wrzucic implementacje, ktora implementuje jedno i drugie i to przekazywac w testach, ale jak cos to moge klepnac prototyp. dalej przewinałem to samo wideo to tam nawet sprytniej zrobił z articleRepository xD https://youtu.be/ILBX9fa9aJo?t=3647 - hcubyc 2019-03-17 00:20
a zwykłe implementacje to po prostu w konfigracji DS korzystasz z tej samej bazy/kolekcji/whatever - hcubyc 2019-03-17 00:22
Posłuchałem fajne, chce dokończyć później ale jakość troche słaba pod względem obrazków :D - scibi92 2019-03-17 10:43

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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