Sposób konfiguracji beanów

0

W jaki sposób konfigurujecie beany w Springu? Przez adnotaję np. @Service, @Component itp nad klasami. czy robicie jedną klasę konfiguracyjną z @Configuration i tworzycie każdą klasę i jej zależność ręcznie i wystawiacie jeden bean np. jakąś fasade? To drugie podejście jest niby "czystsze" i widziałem je z dwa razy na jakiś prezentacjach, ale z drugiej strony w końcu po to powstał ten kontener IoC, żeby nie tworzyć tych wszystkich klas ręcznie i nie tracić czasu na to.

0

Z reguły ręcznie w klasie konfiguracyjnej z prostego powodu: stosując adnotacje typu service/component itp wymuszasz aby pola klasy które normalnie lądują w konstruktorze też były springowymi beanami (bo inaczej jak ma je sobie wstrzyknąć?).

A nie wszystko musi/powinno być beanem springowym.

https://stackoverflow.com/questions/67691575/when-should-you-use-configuration-instead-of-service-controller-component-fo

4
Nofenak napisał(a):

ale z drugiej strony w końcu po to powstał ten kontener IoC, żeby nie tworzyć tych wszystkich klas ręcznie i nie tracić czasu na to.

:-)
To chyba doskonałe podsumowanie (braku) sensu kontenerów IoC/DI.

2
Nofenak napisał(a):

ale z drugiej strony w końcu po to powstał ten kontener IoC, żeby nie tworzyć tych wszystkich klas ręcznie i nie tracić czasu na to.

Kontener IoC optymalizuje łatwy problem (przyrostowe projektowanie aplikacji tak, żeby drzewko zależności miało sens) zastępując go cięzkim problemem (syf w drzewku zależności, bo nie trzeba o niego dbać, czytanie dokumentacji frameworku jak coś się zepsuje).

1
Nofenak napisał(a):

W jaki sposób konfigurujecie beany w Springu? Przez adnotaję np. @Service, @Component itp nad klasami. czy robicie jedną klasę konfiguracyjną z @Configuration i tworzycie każdą klasę i jej zależność ręcznie i wystawiacie jeden bean np. jakąś fasade? To drugie podejście jest niby "czystrze" i widziałem je z dwa razy na jakiś prezentacjach, ale z drugiej strony w końcu po to powstał ten kontener IoC, żeby nie tworzyć tych wszystkich klas ręcznie i nie tracić czasu na to.

To zależy od wielkości projektu.
Małe projekty można faktycznie ogarnąć przez component-scan i to będzie działało fajnie.
Duże projekty, z wieloma konfiguracjami itp. już lepiej ogarniać ręcznie, tj.


@Configuration
@Import({MyConfig1.class, MyConfig2.class...}) // Jeśli potrzeba
public class MyApp { 
   // ...

   @Bean
   public RequiredBean someBeanA() {
      return new RequiredBean();
   }

   @Bean
   public OtherBean someBeanB(RequiredBean bean) {
      return new OtherBean(bean);
   }
}

Wtedy to nawet nieźle działa, dopóki tylko pilnuje się zależności pomiędzy konfiguracjami i nie wrzuca do beanów wszystkiego, co niepotrzebne. Np. widziałem wiele razy, jak ludzie z uporem robili coś takiego:


@Configuration
public class MyDatabaseConfig { 
   // ...

   @Bean
   public DataSource myDataSource() {
      // create DataSource
   }

   @Bean
   public JdbcTemplate jdbcTemplate(DataSource datasource) {
      return new JdbcTemplate(datasource);
   }
}

w sytuacji, w której myDataSource wykorzystywany jest tylko i wyłącznie w tej klasie. Po co ładować to do kontekstu? Nie wiem - za każdym razem, kiedy pytałem ludzi po cholerę to robią nie dostałem dobrej odpowiedzi.

0

Mieszanie i jest to najlepszy sposób jak na razie. Poza XMLem oczywiście.

90% beanów jest standardowa i zależy tylko od innych beanów. Jeżeli coś nie jest beanem springowym (nie ma adnotacji) lub wymaga poprawek młotkiem po wywołaniu konstruktora, to tworzę to w pliku konfiguracyjnym.

1

Wiecie coooo ....

Ja to z tramwaju "wstrzykiwanie" to "wysiadłem na przystanku Niepodległosć".
Przecież Wy w większości znacie te czasy, "radosnego", prostego wstrzykiwania jakiś konfiguracji, przy nadal zachowaniu struktury projektu określonej kodem, gdzie DI to zdecydowanie było POZYTYWNĄ wartością.

Kiedy to się wynaturzyło w jakies koszmary ? - bo jeśli wstrzykiwane beany trzeba jakoś specjalistycznie konfigurować w sposób bardzo "sophistocated", to nie jest ok.
Przecież pomysłodawcy DI nie byli jakimiś diabłami wcielonymi czy idiotami, to się stało pózniej

na marginesie, muszę znaleźć materiały historyczne o początkach wstrzykiwania. Chyba ze ktos wskaże życiorys twórców idei, będę miał szybciej.

Lubię to nie tylko w programowaniu, ale we wszelich hobby z jakimi mam wspólnego, w historii państw, armii (tak, z dojrzałością polubiłem historę - w szkole miałem permanentnie tróję). Historię rozumianą nie jako wykuwanie dat, ale jako zwiazki, powiązania, wynikania, intencje założyciela (indywidualnego czy zbiorowego)

1
ZrobieDobrze napisał(a):

Przecież pomysłodawcy DI nie byli jakimiś diabłami wcielonymi czy idiotami, to się stało pózniej

Kontenery DI mają podłoże historyczne:

  1. mało RAMu 20 lat temu -> pakowanie wielu aplikacji na jeden JVM -> serwery aplikacji -> serwlety ładowane przez "class.forName" i bezargumentowy konstruktor -> nie można przekazać kontekstu do serwletu -> trzeba wymyśleć jakiś DI framework, który radzi sobie nawet jak obiekty są tworzone przez bezargumentowy konstruktor (choćby na testy)

  2. Brak Generyków w javie 20 lat temu -> nie da się zrobić Provider<T>, tak żeby nie bolało -> programujemy w XML + kontener DI

  3. (pomniejszy problem) Brak lambda przed java 8 -> nie da się zrobić ludzko aspektów -> rypiemy aspekty na runtime proxy.

Generalnie 20 lat temu kontenery DI w javie miały jakiś sens, a mimo to robiło się gigantyczne projekty bez nich :-)

0
jarekr000000 napisał(a):

serwlety ładowane przez "class.forName" i bezargumentowy konstruktor -> nie można przekazać kontekstu do serwletu

Na marginesie tego, jak poszła Java zwłaszcza EE, sobie myślę, nie można było "w onym czasie" narzucić konwencji, że używamy newInstance(context)
To technicznie od zawsze było możliwe, nie byliśmy skazani na bezargumentowy konstruktor

A C# uzywamy takiej konwencji, konstruktor jest zawsze taki sam (argumentowy), choć powołanie instancji jest z refleksji a nie z kodu.
Najwyzej by poleciał wyjatek

0
ZrobieDobrze napisał(a):

Kiedy to się wynaturzyło w jakies koszmary ? - bo jeśli wstrzykiwane beany trzeba jakoś specjalistycznie konfigurować w sposób bardzo "sophistocated", to nie jest ok.

W przypadku Springa to jest klasyczny przypadek antywzorca: https://exceptionnotfound.net/the-golden-hammer-anti-pattern-primers/ , a konkretniej - używanie Spring Frameworka do pisania nowego frameworka.

Widziałem co najmniej kilkanaście projektów tego typu projektów. Zawsze ten sam wzorzec: ludzie ogarniający jako-tako Springa z poziomu użytkownika frameworka wpadają na pomysł stworzenia aplikacji modularnej. Tj. takiej, która pozwala na łatwe zdefiniowanie modułów, które będą automatycznie łączone w większe całości.

No i jako, że takowym specjalistom od Springa słówko "moduł" od razu zaczyna się kojarzyć z konfiguracją springową, to powstaje pierwszy, bardzo prosty PoC. Taki, który działa - tj. programista importuje bibliotekę, potem tworzy odpowiednią implementację klasy, rejestruje beana o odpowiedniej nazwie, a dalej ten bean wpada jako zależność do listy predefiniowanych modułów. Wszystko działa, kod zajmuje kilka linijek, nic tylko się cieszyć.

Dopiero potem zaczynają się schody, tj. trzeba projekt rozwijać. Predefiniowane moduły robią się coraz cięższe, coraz więcej jest magicznych konfiguracji, którą znają tylko autorzy rozwiązania i coraz łatwiej o pomyłkę. Ludzie, którzy stworzyli owe modułowe rozwiązanie odchodzą z projektu, większość nowych rzeczy tworzone jest bez zastanowienia za pomocą kopiuj+wklej. Do tego dochodzi to nieszczęsne autoskanowanie po pakietach - i masz gotowy przepis na katastrofę.

W rezultacie coś, co byś wyklepał w dzień w czystym Springu zajmuje ci trzy dni, bo musisz się zastanawiać, czy to owy magiczny framework źle działa, czy też to ty coś pokpiłeś.

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