Spring to jeden z bardziej popularnych frameworków Javy, jest również jedną z najbardziej pożądanych przez pracodawców umiejętności, postanowiliśmy więc dzisiejszy wpis całkowicie popświęcić tej technologii.

Na samym początku parę słów uzupełnienia do poprzedniego artykułu o tematyce wzorców projektowych.

Chodzi o Singletona – jeden z użytkowników słusznie zwrócił uwagę, że dwa sposoby, które zostały przedstawione, mogą być niewystarczające. Maciej wypunktował, iż sposoby tworzenia Singletonów, pokazane na obrazku, nie są bezpieczne do pracy z wieloma wątkami (a takie są często wykorzystywane w praktyce), dlatego poniżej dodajemy małe uzupełnienie do poprzedniego artykułu. Dziękujemy za trafną uwagę!

Jak zaimplementować Singletona w taki sposób, aby był bezpieczny do pracy z wieloma wątkami?

Jeżeli podczas prezentowania Singletonów na rozmowie przedstawimy najprostszą możliwą implementację (tę implementację można zobaczyć w artykule nt. wzorców projektowych), mogą nas poprosić o napisanie Singletona, który jest bezpieczny do pracy z wieloma wątkami. Istnieje całkiem sporo metod ich tworzenia, poniżej przedstawiamy dwa najbardziej odporne i działające rozwiązania:

Rys. 1 Tworzenie Singletona poprzez Enumy. Nie występuje tutaj problem z serializacją oraz odbiciem (reflection). Warto jednak zapamiętać, że dane zapisane w Singletonie zostają utracone po serializacji (Zmienna name oraz age będzie pusta po deserializacji).
Rys. 2 Inicjalizacja Singletona drugą metodą, bez użycia Enum’a (przed Javą 1.5)

Obydwa rozwiązania są odporne na problem odbicia (reflection) oraz serializacji. Warto jednak wspomnieć, że rozwiązanie drugie jest dużo bardziej skomplikowane i czasochłonne od rozwiązania numer jeden – dlatego preferowane jest tworzenie Singletonów przy pomocy Enum’a.

Czym jest framework Spring?

Spring jest jednym z najpopularniejszych frameworków Javy, używanym głównie do aplikacji typu Enterprise. Głównych cechy tego frameworka używa się do tworzenia wszystkich aplikacji, ale największe możliwości osiąga się przy produkcji aplikacji webowych. Dzięki wykorzystaniu Springa możemy osiągnąć luźne łączenie (loosecoupling) pomiędzy poszczególnymi komponentami przy użyciu wstrzykiwania zależności (DependencyInjection), bądź pozwalać nam na wykorzystywanie zalet programowania aspektowego.

>> Sprawdź nasze aktualne oferty w obszarze: Java Developer

Jakie są główne zalety tego Frameworka?

  1. Lekkość – podstawowa wersja Springa jest niezwykle lekka, zajmuje jedynie około 2MB.
  2. Inversion of control (odwrócenie sterowania) – polega na tym, iż funkcja sterowania przepływem jest przypisana do frameworka (Springa). Oznacza to między innymi, że oddzielamy część [co zrobić] od funkcji [kiedy zrobić], oraz to że część, która odpowiada za kolejność wykonania wie jak najmniej o tym co jest do wykonania.  Ilustracją tego zachowania może być przykładowo graficzny interfejs, który pozostawia „puste” miejsca w swojej funkcjonalności. Interfejs może być wykorzystywany do różnych celów w zależności od zaimplementowanej funkcjonalności i to on steruje przepływem informacji. Jest luźno powiązany z funkcjonalnością, przez co może być ponownie wykorzystany w przyszłości (zmieniamy tylko „puste” miejsca).
  3. Spring container (kontener Springa) – Spring przechowuje oraz zarządza cyklem życia i konfiguracją obiektów używanych przez aplikację.
  4. Framework do obsługi MVC – Spring posiada dobrze zdefiniowany Framework do tworzenia aplikacji w oparciu o model projektowy MVC. Dzięki temu, tworzenie aplikacji jest zdecydowanie prostsze i szybsze. Spring MVC możemy również wykorzystywać do tworzenia aplikacji Webowych, jak i web serwisów (RESTful web services).
  5. Łatwość w pisaniu testów – dzięki temu, że logika biznesowa nie zawiera bezpośrednich zależności, jesteśmy w stanie szybko i łatwo napisać testy jednostkowe, używając mock’owych (pozornych) beanów.

Czym jest DependencyInjection (iniekcja zależności)?

Iniekcja zależności pomaga nam połączyć różne obiekty w naszej aplikacji, które powinny ze sobą współpracować w luźny sposób, umożliwiając nam „luźne łączenie” (loosecoupling) poszczególnych elementów. Dzięki niej jesteśmy w stanie posklejać elementy razem (nie tworząc „twardych” zależności), zachowując przy okazji ich niezależność. Płynie z tego kilka dużych plusów – łatwość w rozbudowie aplikacji, oddzielenie warstw aplikacji oraz łatwość w pisaniu testów. Iniekcję można wykorzystać np. poprzez wykorzystanie iniekcji w konstruktorze (przy pomocy adnotacji @Autowired), poprzez iniekcję z wykorzystaniem setterów oraz iniekcję bezpośrednio w pola naszej aplikacji. Pierwszy sposób odbywa się, gdy kontener Springa odwołuje się do konstruktora z określoną liczbą argumentów (każdy argument przedstawia pojedynczą zależność). W drugiej metodzie kontener wykorzystuje settery. Mechanizm ten możemy implementować przy pomocy konfiguracji plików XML-owych Springa lub poprzez wykorzystanie adnotacji.

Rys. 3 Przykładowa iniekcja zależności poprzez konstruktor.
Rys. 4 Iniekcja z użyciem adnotacji @Autowired bezpośrednio przy deklaracji zmiennej.

Czym są Beany Springa (Spring Beans)?

Beany są to obiekty, które tworzą trzon Twojej aplikacji. Zarządza się nimi poprzez kontener Springa (Spring IoCcontainer). Tworzymy je na podstawie metadanych z plików konfiguracyjnych, które dostarczamy do kontenera Springa. Pliki konfiguracyjne mogą być dostarczone np. w formie plików XML-owych lub przy wykorzystaniu adnotacji @Configuration wraz z wykorzystaniem @Bean.

Jakie wartości może przyjmować zakres Beana (Bean scope)?

Istnieje pięć (przy czym trzy z nich odwołują się do tworzenia aplikacji webowych) różnych wartości, które można ustawić jako zakres beana:

a) singleton – jeżeli bean ma ustawiony zakres jako singleton, to tylko jeden obiekt tego beana będzie zarządzany przez kontener Springa. Oznacza to, że jeżeli kilka razy będziemy chcieli „pobrać” tego beana, to za każdym razem będziemy dostawać tę samą instancję Beana.

b) prototype – za każdym razem, kiedy próbujemy pobrać Beana, dostajemy nową instancję tego beana (tzn. np. poprzez iniekcję do innego beana, lub pobranie bezpośrednio przy użyciu metody .getBean().

c) request – używane w aplikacjach webowych. Ustawia zakres beana na cykl życia pojedynczego żądania http. Oznacza to, że każde żądanie będzie posiadało swoją własną instancję beana.

d) session – używane w aplikacjach webowych. Zakres beana równa się zakresowi sesji http.

e) global-session – jak wyżej, z tym że odnosi się do globalnego zakresu sesji http.

Jakie są różne rodzaje wiązania (autowiring) beanów Springa?

Rodzaj wiązania ustawiamy wpisując określoną wartość do właściwości autowire podczas deklarowania beanów w pliku xml. Musimy pamiętać również, że nie możemy automatycznie powiązać prymitywnych typów danych, Stringów oraz Klas. Istnieje kilka rodzajów wiązania beanów:

a) Wiązanie poprzez typ danych (autowire=”byType”). Oznacza to w skrócie, że jeżeli typ danych pierwszego beana jest kompatybilny z typem danych właściwości (pola) drugiego beana, „podłącz” tego pierwszego beana pod pole drugiego beana.

b) Wiązanie poprzez nazwę (autowire=”byName”). Wiązanie to bierze pod uwagę nazwę beana oraz nazwę pola w innym beanie. Jeżeli nazwa beana będzie odpowiadać nazwie pola w innym beanie to Spring automatycznie podłączy beana pierwszego pod pole w beanie drugim.

c) Łączenie poprzez konstruktor (autowire=”constructor”). Opiera się na podobnej zasadzie jak wiązanie poprzez typ danych z tą różnicą, że nie są przeszukiwane pola beana, pod który mają być podłączone inne beany, ale konstruktor (i typy danych parametrów konstruktora).

d) Wiązanie poprzez auto detekcję (autowire=”autodetect”) oznacza użycie któregoś z dwóch typów. W przypadku, gdy, do beana dostarczymy konstruktor z argumentami, to Spring najpierw spróbuje wykorzystać wiązanie poprzez konstruktor, natomiast jeżeli w beanie nie występuje żaden konstruktor, to Spring spróbuje podłączyć beany wykorzystując metodę byType

Czym jest Spring Security?

Spring security jest to wewnętrzny framework Springa, który odpowiada przede wszystkim za uwierzytelnianie oraz autoryzację w aplikacjach typu Enterprise. Jej działanie opiera się głównie o filtry, przez które musi „przejść” każde zapytanie domagające się dostępu do naszej aplikacji. Jeżeli zapytanie nie zostanie zweryfikowane pozytywnie to Spring Security odmówi mu dostępu do naszej aplikacji. Dzięki niemu możemy jasno określić, do jakiej części aplikacji może mieć dostęp użytkownik niezalogowany, zalogowany, admin itp.

Tutaj właściwie zakończymy pierwszą część naszego artykułu, zawiera ona kilka najczęstszych pytań, pojawiających się na rozmowach odnośnie Springa. W następnej części podrzucimy Wam trochę więcej pytań, które mogą się pojawić, oraz pokażemy jak stworzyć prosty i działający projekt w Springu.

Widzimy się w kolejnym artykule! 😉

Autor: Marek Makuch

Oryginalny wpis pojawił się na naszym blogu w lipcu 2018r.

logo IT-Leaders

IT-Leaders.pl to pierwsza w Polsce platforma łącząca Specjalistów IT bezpośrednio z pracodawcami. Anonimowy, techniczny profil i konkretnie określone oczekiwania finansowe to tylko niektóre z cech wyróżniających platformę. Zarejestruj się i zobacz jak Cię widzi pracodawca.

Comments (1)

  1. Pingback: Rozmowa kwalifikacyjna z Javy? Żaden problem! Cz. VII (Spring) -

Comments are closed.