Jak działa kontener IoC?

2014-04-02 15:36
0

Chciałbym zapytać, jak działa kontener IoC na przykładzie Springa. Zanim zacznę się wgłębiać w tutoriale, chciałbym mieć ogólny pogląd na tę rzecz.
Z tego co wiem, to kontener IoC powstał po to, by wstrzykiwanie zależności (np poprzez konstruktor) stało się łatwiejsze. Nie wiem czy dobrze się orientuje, ale pozwala on zniwelować problem łańcuchowych zależności (chaining dependencies) np new D(new C(new B(new A()))). Jest jednym z 3 wyjść aby uniknąć tych łańcuchowych zależności, koło dwóch brzydkich: singleton i serviceloader. Ma ułatwić testowanie i mockowanie obiektów.
Teraz: jak to wygląda w praktyce? W jaki sposób pozwala uniknąć tych chaining dependencies? W jaki sposób dostarcza się zależności? Prosiłbym o jakiś przykład (nie pogardzę kawałkiem kodu).

Pozostało 580 znaków

2014-04-02 15:47
3

Najpierw prosty przykład:

@Repository
public class ClientDaoIml implements ClientDao{
    public List<Client> getAllClients(){...}
}

Jeśli teraz w kontekście springowym ustawimy sobie konfiguracje annotation-based i ustawimy żeby skanował pakiet w którym mamy taką klasę to Spring już sobie ją ogarnął. Po odpaleniu aplikacji kontener Springa sam stworzy sobie obiekt takiej klasy i będzie nim zarządzał. Jak możemy takiego obiektu użyć?

@Controller
public class MagicznyKontroler{
    @Inject
    private ClientDao clientDao;
} 

I tyle. Nic więcej. Spring automagicznie sprawi że pole clientDao zostanie zainicjalizowane moim serwisem.

Warto wspomnieć: Wstrzykiwać da sie tylko do obiektów zarządzanych przez springa -> czyli de facto tylko do innych serwisów (klas oznaczonych m.in. jako @Component, @Repository, @Service, @Controller)

Jeśli chodzi o to "jak" to się dzieje, to magii tu nie ma. Spring tworzy sobie te obiekty a potem przypisuje odpowiednie referencje ;]


Na PW przyjmuje tylko (ciekawe!) zlecenia. Masz problem? Pisz na forum, nie do mnie.
edytowany 1x, ostatnio: Shalom, 2014-04-02 15:48
Pokaż pozostałe 10 komentarzy
No może nie bolą, ale to dodtakowy kod, który trzeba "napisać" metodą copy-paste, i trzeba o nim pamiętać. - somekind 2014-04-03 10:10
A konfiguracji w innym miejscu nie trzeba? Dziwna logika. Ten kod gdzieś być musi, bo kontener sobie sam nie wymyśli co i gdzie chcesz wstrzykiwać ;] - Shalom 2014-04-03 10:14
Jeśli tworzysz nową klasę danego typu musisz pamiętać o dodaniu tych adnotacji, prawda? A ja nie muszę, bo konfigurację IoC w oparciu o konwencje już raz napisałem, i zadziała dla każdej nowej klasy. - somekind 2014-04-03 10:25
Tak jak mówiłem - można to w springu też tak skonfigurować jak bardzo chcesz. Ale mnie interesuje jak chcesz tak automagicznie skonfigurować wstrzykiwanie... Skąd kontener wie które property chcesz wstrzykiwać a których nie? Albo jeśli masz kilka serwisów o tym samym interfejsie to jak chcesz specyfikować ich nazwy? - Shalom 2014-04-03 10:30
Prostą konfigurację na zasadzie "wstrzyknij wszystko" w springu można też zrobić. Jeżeli używasz Guice to jest jeszcze prostsze, bo wystarczy trzymać się konwencji z konstruktorem, a nie setterami. Rzecz zaczyna się komplikować jak masz wiele beanów o takim samym interfejsie np. kontrolerów webowych. Wtedy zaczyna się "magia" polegająca zazwyczaj na łamaniu konwencji, a to już jest gorsze niż te adnotacje. - Koziołek 2014-04-03 10:59

Pozostało 580 znaków

2014-04-03 12:20
0

ZTCW to pod maską kontener IoC skanuje wybraną część classpatha, refleksją sprawdza klasy w poszukiwaniu adnotacji/ konwencji/ etc, potem buduje graf zależności i w momencie wyciągania obiektu z kontenera buduje te obiekty które w tym stworzonym grafie są zależnościami wyciąganego obiektu. Potem refleksją są wywoływane settery/ konstruktory i dostajemy żądany obiekt. Dzięki budowaniu grafu kontener IoC może sobie przeanalizować kod by budować klasy w odpowiedniej kolejności. Dzięki grafowi może też znajdować cykle i wtedy rzucać wyjątkiem.

Oprócz typowego kontenera IoC który buduje graf dynamicznie jest jeszcze dostępny bardziej statyczny IoC w postaci Cake Pattern w Scali.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 2x, ostatnio: Wibowit, 2014-04-03 12:25

Pozostało 580 znaków

2014-04-03 13:28
0

Dzięki grafowi może też znajdować cykle i wtedy rzucać wyjątkiem.

Niekoniecznie ;) Bo cykl właściwie w niczym specjalnie nie przeszkadza - Spring potrafi sobie z tym radzić za pomocą wstrzykiwania specjalnych proxy w takie miejsca. Problem pojawia sie dopiero kiedy wstrzykujesz coś co już wcześniej jest proxowane -> na przykład obiekt który ma jakieś @Transactional, wtedy dopiero się wysypie.


Na PW przyjmuje tylko (ciekawe!) zlecenia. Masz problem? Pisz na forum, nie do mnie.
to proxy potem widać w stacktrace? - Wibowit 2014-04-03 13:55
Tak, ale widać po jego nazwie co to za proxy i widać dokładnie gdzie poleciał jakis wyjątek ;) - Shalom 2014-04-03 14:09

Pozostało 580 znaków

Liczba odpowiedzi na stronę

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