Spring- co to znaczy utworzyć beana ?

0

Cześć,
jestem na etapie poznawania springa.
Aczkolwiek nie rozumiem paru rzeczy. Czyta tutoriale, kombinuję, ale często w tutorialach piszą rzeczy, których nie jestem w stanie zrozumieć. Może ktoś to wyłtumaczyć ?

  1. Co to znaczy utworzyć beana ?
  2. W którym momencie następuje wstrzyknięcie zależności ?
  3. Jaka jest ogólna idea tych beanów ?
  4. W którym momencie jest parsowany plik xml Springa ? Tzn jak to działa ? JVM to odpala ? Na początku ?
0
  1. Zgaduje ze autorowi tutoriala chodzi o utworzenie klasy która będzie miała adnotacje @Named albo @Service czyli będzie zarządzana przez Springa/CDI
  2. Generalnie w chwili tworzenia obiektów którymi Spring zarządza, czyli kiedy zostanie wczytany kontekst definiujacy wszystkie beany
  3. Nie do końca rozumiem pytanie.
  4. Wtedy kiedy go załadujesz. W przypadku aplikacji Spring MVC dzieje się to przy starcie aplikacji w kontenerzem ale dla innych aplikacji musisz sam utworzyc sobie kontekst i załadować deskryptor.
0

musisz sam utworzyc sobie kontekst i załadować deskryptor.

Co znaczy załadować deskryptor ?
Bo wiem, że tworzy się obiekty Springowe, podaje ścieżkę do xml-a.

  1. Generalnie w chwili tworzenia obiektów którymi Spring zarządza, czyli kiedy zostanie wczytany kontekst definiujacy wszystkie beany

Którymi obiektami zarządza spring ?

1

Konfiguracja Springa to niekoniecznie xml. Ba, od dawna odchodzi się od xmla na rzecz class configuration, ale to akurat szczegół. Chodziło mi tutaj np. o utworzenie ApplicationContext albo BeanFactory do którego podajesz swój xml (albo inną konfiguracje)

Spring zarządza obiektami które są zdefiniowane w kontekście. Zwykle to klasy opatrzone odpowiednimi adnotacjami (Named, Service, Repository etc) lub obiekty explicite zdefiniowane w konfiguracji jako @Bean lub <bean> (dla xmla). Dodatkowo te wszystkie klasy muszą być widoczne dla springa wiec jeśli masz jakiś component-scan który wskazuje na to które pakiety skanować w poszukiwaniu obiektów to musisz podać odpowiedni pakiet.

0

Ok, wszystko wydaje się zawiłe,
no powiedzmy, że mam w xmlu beana o id=moobiekt.
Kiedy ten bean zostanie stworzony ? Co moze się stać w trakcie tworzenia takiego beana ? Wiem np., że mogą zostać ustalone składowe, np z jakiegoś pliku konfiguracyjnego. ALe czy tylko tyle ?>

0

Ja od siebie polecę książkę https://www.manning.com/books/spring-in-action-fourth-edition (lub jej polski odpowiednik, jeśli z ang problem), jeżeli tutoriale Ci nie podchodzą ;)

0

Zostanie utworzony zapewne kiedy ten xml zostanie podany do jakiegoś ApplicationContext. Wiec jak sobie zrobisz new ClasspathApplicationContext("moj.xml"); czy coś w tym stylu. W trakcie tworzenia ten bean otrzyma zalezności które zadeklarowano przez @Inject, @Autowired albo explicite w tym twoim xmlu. Dodatkowo ten twój obiekt sam też zostanie wstrzyknięty do innych beanów które go wymagają.

0

Wydaje się, że bean to jest tak na prawdę obiekt.. bo na czym niby polega różnica ?

0
Pijany Szczur napisał(a):

Wydaje się, że bean to jest tak na prawdę obiekt.. bo na czym niby polega różnica ?

Pewnie, że jest, tylko zarządzany przez Springa, jak wspomniał wyżej @Shalom ;)

0

Dodatkowo ten twój obiekt sam też zostanie wstrzyknięty do innych beanów które go wymagają.

Możesz rozwinąć ? Kiedy inne beany potrzebują mojego obiektu ?

0

Kiedy w innej klasie zarządzanej przez Springa/CDI, dodasz zależność na jakiegoś beana, np:

 
@Component
public class Boo {
  public Boo() { }
}

@Component
public class Foo {

  Boo boo;

  @Autowired
  public Foo(Boo boo) {
    this.boo = boo;
  }
}

Dzięki adnotacji @Autowired na konstruktorze(może być bezpośrednio na polu) spring spróbuje wstrzyknąć zależność, jaką jest Boo, do klasy Foo.

1

No dobra, to na przykladzie:
Wyobraźmy sobie że piszesz klasę odpowiedzialną za zapisywanie plików pewnego typu. Ta klasa zapisuje pliki w podanej lokalizacji ale lokalizacja moze być względna lub bezwzględna. Więc dla ułatwienia sprawy tworzysz nową klasę, która zajmuje się ogarnianiem tych ścieżek, tzn daje ci bezwzględną ścieżkę dla podanej bezwzględnej lub względnej. Jak widać twoja klasa zapisująca pliki potrzebuje tej klasy do działania.
No ale teraz ten nasz ogarniacz ścieżek w rzeczywistości rozpatruje ścieżki względne względem jakiegoś katalogu roboczego zdefiniowanego w konfiguracji aplikacji. Więc potrzebuje do pracy obiektu który daje dostęp do konfiguracji.

Łatwo też zauważyć że w sumie to te obiekty są bezstanowe i wystarczy ci tylko jeden obiekt każdego typu i można z takiego obiekty korzystać z wielu miejsc bez problemów.

Jeśli robisz to za pomocą IoC jak Spring to tworzysz sobie te klasy, oznaczasz jako beany a zależności oznaczasz jako @Inject i nie zastanawiasz się "skąd" sie bierze taki czy inny obiekt.

W przypadku klasycznym musiałbyś gdzieś sam ręcznie utworzyć tą hierarchie obiektów, rozkminić kolejność tworzenia i odpowiednio poustawiać parametry. Co wiecej jak się nagle okaże że "potrzeba ci jeszcze jakiegoś innego obiektu" to będziesz znowu rozkminiał jak to posortować żeby móc ten obiekt przekazać tam gdzie ci potrzebny.

0
  1. Co oznacza @Component ? Wiem, że to adnotacja, ale nie wiem co rozumie przez nią Spring.
  2. Jak rozumiem Boo boo jest zależnością w klasie Foo.
    Wobec tego w momencie tworzenia jakiegoś obiektu klasy Foo trzeba jakoś ustawić boo. Domyślnie byłby to nil. Natomiast skąd Spring będzie wiedział jakie własności (atrybuty) ma mieć obiekt boo ?
0
  1. Component to po prostu generyczny Singleton
  2. Musisz Springowi powiedzieć. Albo będzie tam konstruktor bezparametrowy, albo konstruktor z samymi wstrzykniętymi parametrami albo musisz explicite przez <bean> albo @Bean zdefiniować jak dany obiekt utworzyć.
0
  1. @Component, @Named, @Service, @Repository (i inne określone adnotacje) informują springa, że te klasy są właśnie beanami i mają być przez niego zarządzane. Dodatkowo, aby spring je 'wykrył', musisz mieć dobrze ustawiony ComponentScan do pakietu, w którym znajduje się ta klasa. O różnicach tych adnotacji doczytaj.
  2. W tym momencie nie ma żadnych pól w klasie Boo, więc co ma tam ustawiać?
0
Pijany Szczur napisał(a):
  1. Co to znaczy utworzyć beana ?

W przypadku Springa - "utworzyć beana" oznacza "stworzyć obiekt w kontekście Springowym (ApplicationContext i pochodne)

Pijany Szczur napisał(a):
  1. W którym momencie następuje wstrzyknięcie zależności ?

Zaraz po stworzeniu obiektów.

Pijany Szczur napisał(a):
  1. Jaka jest ogólna idea tych beanów ?

Żeby przenieść ręczne wstrzykiwanie zależności do kontekstu Springowego. Albo bardziej ogólnie - żeby część rzeczy rozwiązywać za pomocą deklaracji zamiast za pomocą dokładnych instrukcji.

Pijany Szczur napisał(a):
  1. W którym momencie jest parsowany plik xml Springa ? Tzn jak to działa ? JVM to odpala ? Na początku ?

JVM nic sam z siebie nie robi. XML Springowy jest parsowany w momencie utworzenia odpowiedniego obiektu. Dla aplikacji webowych - zazwyczaj przy starcie servletu. Przy aplikacjach offline - trzeba ręcznie odpalić kontekst.

0

Dzięki wielkie za odpowiedzi, wiele rozjaśniają.
Spróbuję podsumować.

  1. Czym są zależności ? To nic innego jak składowe pewnego obiektu. Np, jak podał @Shalom to ścieżka, która będzie czytana z pliku konfiguracyjnego.
  2. Na czym polega wstrzyknięcie zależności ? Podczas tworzenia obiektu (beana) Spring ustawia te pola (składowe) zgodnie z tym jak go poinstruowaliśmy (albo xml, albo adnotacje). Tak np. może być, gdy mamy aplikację webową i tworzymy obiekt reprezentujący formularz. Oczywiście można by to robić ręcznie, ale używając Springa, prosimy go o to, żeby stworzył nam taki obiekt na podstawie danych z fronendu (czyli wstrzykuje dane). Modyfikacja takiego procesu jset wówczas łatwa.

Czy mam słuszność ?

PS ok, to przećwiczę. Co oprócz wstrzykiwania zależności jest jeszcze bazą w Springu o której warto doczytać ?

0

Akurat ładowanie danych z formularza do obiektu DTO nie ma nic wspólnego z wstrzykiwaniem zależności. I w ogóle źle zrozumiałeś. Zależnością w moim przykładzie nie była żadna ścieżka tylko OBIEKT/SERWIS który realizował jakieś funkcjonalnosci - na przykład zamieniał ścieżki względne na bezwzględne. I znowu ten serwis polegał na innym serwisie (a nie na wartości!) który umożliwiał dostęp do konfiguracji.

0

To prawda, ale któraś klasa będzie musiała poznać ścieżkę (stringa). I właśnie jego możemy wstrzyknąć do TEJ klasy (która musi go znać).

Inna natomiast sprawa wstrzyknięcie obiektu (który odpowiada za dekodowanie ścieżki) do obiektu, który dokonuje zapisu *de facto do klasy.

A czego nie można tak realizowac tworzenia obiektu z formularzu ?

0

No jeśli zakładasz że ścieżka do katalogu roboczego nie moze ulec zmianie, ale to niekoniecznie prawda ;) Równie dobrze aplikacja moze pozwalać na jej zmianę i wtedy potrzebujesz obiektu który zapisuje/wczytuje konfiguracje z bazy danych czy jakiegoś xmla.

Nie chodzi o to że nie można tak tworzyć obiektu z formularza, bo można i nawet trzeba. Ale nie ma to nic wspólnego ze wstrzykiwaniem zależności. To jest zwykły data binding.

0

W
takim razie trochę nie rozumiem na poziomie samej idei tych wstrzyknięć.

Wydawało mi się, że wstrzyknięcia są właśnie po to, żeby zautomatyzować tworzenie obiektów. I własnie w ten sposób chciałbym dostarczać plik konfiguracyjny (ścieżkę).
Umówmy się, że wklepię go do xmla i przekażę do klasy. Wówczas z poziomu pliku xml mogę dostarczać co raz to inną ścieżkę.
(Oczywiście są prettyPlaceHoldery- w każdym razie mogę wklepać w xml dla odpowiedniego beana ${config_path}.

Wtedy w momencie tworzenia obiektu odpowiadającego temu beanowi spring odnajdzie wartość config_path - udało się, wstrzyknąłem ścieżkę. Dalej, obiekt który tą ścieżkę dostarczy, też zostanie wstrzyknięty (referencja) do obiektu, który z niego będzie korzystał (ma go jako swoją składową).

0

Nie no oczywiście że tak mozesz, ale ile takich potrzeba? Parametry bazy danych zwykle sie tak wrzuca, ale co innego? Sytuacji kiedy wstrzykujesz serwisy między sobą, jakieś DAO, serwisy do kontrolerów itd jest nieporównywalnie więcej ;)

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