
Poznasz kluczowe cechy Spring Boot, automatyczną konfigurację, wbudowany serwer Tomcat i szybkie tworzenie REST API.
Spring Boot - Boot - Boot z ang. oznacza uruchomić
W tej lekcji wprowadzę Cię w świat Spring Boota! Dowiesz się, czym jest framework Spring i dlaczego jest tak popularny w tworzeniu aplikacji biznesowych. Pokażę Ci, jak Spring Boot upraszcza i przyspiesza pracę, automatyzując żmudne konfiguracje. Wyjaśnię, dlaczego warto od razu zacząć od Spring Boota, zamiast grzebać w ustawieniach "gołego" Springa. Omówię, czym jest backend i jak łączy się z frontendem. Przygotuj się na solidną dawkę wiedzy, która pozwoli Ci szybko wystartować z tworzeniem aplikacji w Javie!
Zainstalujesz JDK 21, Maveni IntelliJ IDEA, przygotowując środowisko do pracy.
Maven automatycznie pobiera potrzebne pliki do działania Twojej aplikacji, kompiluje kod, uruchamia testy i tworzy gotową aplikację. Dzięki niemu nie musisz ręcznie dodawać bibliotek ani wpisywać skomplikowanych komend – wystarczy jeden plik konfiguracyjny (pom.xml).
Gradle automatycznie pobiera potrzebne pliki, kompiluje kod, uruchamia testy i tworzy gotową aplikację. Dzięki niemu nie musisz ręcznie dodawać bibliotek ani wpisywać skomplikowanych komend – wystarczy jeden plik konfiguracyjny (build.gradle lub build.gradle.kts).
W tej lekcji pokażę Ci, jak zabrać się za tworzenie projektu w Spring Boocie. Omówimy dwie drogi: uniwersalną, która zadziała w każdym edytorze kodu, oraz taką, która jest szybsza, jeśli korzystasz z IntelliJ IDEA Ultimate.
Uniwersalna metoda polega na skorzystaniu ze strony start.spring.io. Tam, po wybraniu odpowiednich opcji (o których za chwilę), wygenerujesz plik, który potem otworzysz w swoim ulubionym edytorze – czy to Visual Studio Code, darmowej wersji IntelliJ (Community Edition), czy NetBeans.
Jeśli masz IntelliJ IDEA Ultimate, możesz pójść na skróty i stworzyć projekt bezpośrednio w IDE, wybierając opcję "New Project".
Następnie przejdziemy razem przez konfigurację projektu. Najpierw wybierzemy pomiędzy Gradle a Mavenem. Są to narzędzia, które automatycznie pobierają potrzebne pliki, kompilują kod, uruchamiają testy i tworzą gotową aplikację. Wyjaśnię, czym się różnią i dlaczego w tym kursie skupimy się na Mavenie.
Potem wybierzemy język programowania – do wyboru masz Javę, Kotlina i Groovy. W tym kursie będziemy korzystać z Javy, ale jeśli znasz Kotlina, to nie będzie wielkiej różnicy.
Ważna rzecz: wybór wersji Spring Boota. Zawsze bierzemy najnowszą stabilną wersję – unikamy wersji oznaczonych jako "snapshot" lub "M2", bo to są wersje testowe.
Kolejny krok to metadane projektu – czyli informacje takie jak nazwa Twojej firmy (lub "example", jeśli dopiero zaczynasz), nazwa pliku projektu, czytelna nazwa projektu i jego opis.
Ustawimy też wersję Javy – w tym kursie będziemy pracować na wersji 21.
Na koniec zajmiemy się zależnościami (dependencies). To są dodatkowe biblioteki, które możemy dodać do projektu. Na start dodamy Spring Web, żeby mieć od razu wbudowany serwer do obsługi zapytań. Pokażę, jak to zrobić i podkreślę, że w każdej chwili można dodać kolejne zależności.
Pokaże jak wygenerować plik ze strony oraz jak stworzyć projekt za pomocą IntelliJ.
Po przejściu przez te kroki będziesz gotowy, żeby zacząć pisać kod w Spring Boocie!
W tej lekcji zapoznam Cię ze strukturą projektu w Spring Boocie. Pokażę Ci najważniejsze pliki i foldery, żebyś wiedział, gdzie czego szukać.
Zacznijmy od pliku pom.xml. To serce konfiguracji Twojego projektu. W nim znajdziesz informacje o wszystkich zależnościach, czyli dodatkowych bibliotekach, z których korzysta Twoja aplikacja. Pokażę Ci, gdzie w tym pliku znajduje się informacja o dodanej przez nas wcześniej zależności "Spring Boot Starter Web". Wyjaśnię też, jak dodawać kolejne zależności – za pomocą przycisku "Add Starters" lub skrótu Alt + Insert.
Kolejnym ważnym miejscem jest folder src. W nim znajdują się dwa kluczowe podfoldery: test i main.
W folderze test umieszczone będą testy jednostkowe, które sprawdzają, czy Twój kod działa poprawnie. Na razie zostawimy ten folder, ale wrócimy do niego w przyszłości.
Najważniejszy dla nas jest folder main. To tutaj znajduje się "mięso" Twojej aplikacji. Wewnątrz main znajdziesz folder resources, a w nim plik application.properties. Ten plik służy do przechowywania konfiguracji Twojej aplikacji – na razie będzie pusty, ale zapamiętaj, gdzie go szukać, bo w przyszłości będziemy z niego korzystać.
No i wreszcie – gdzie pisać kod? Kod Twojej aplikacji (w Javie) będziesz umieszczać w folderze main/java. Tam właśnie będziemy tworzyć nasz program, ale to już temat na kolejne lekcje.
W tej lekcji skupimy się na adnotacjach w Spring Boocie, a konkretnie na tej jednej, najważniejszej: @SpringBootApplication. Wyjaśnię, że adnotacje w Springu to nie tylko "zwykłe" informacje – dzięki mechanizmowi refleksji (czyli analizie kodu Javy w trakcie działania) mają one realny wpływ na zachowanie aplikacji.
Pokażę Ci, że @SpringBootApplication to tak naprawdę "trzy w jednym" – zawiera w sobie trzy inne adnotacje: @Configuration, @EnableAutoConfiguration i @ComponentScan. Omówię, co każda z nich robi i jak wpływają one na klasę, nad którą się znajdują.
@Configuration oznacza, że dana klasa jest klasą konfiguracyjną – w przyszłości będziemy w niej umieszczać tak zwane "beany", ale o tym później.
@EnableAutoConfiguration to magia Spring Boota – automatycznie konfiguruje wszystkie zależności, które dodaliśmy do projektu (np. Spring Boot Starter Web, który dodaliśmy w poprzedniej lekcji – i który uruchamia serwer Tomcat). Dzięki temu nie musimy ręcznie konfigurować serwera – Spring Boot robi to za nas!
@ComponentScan sprawia, że Spring Boot przeszukuje ten sam pakiet, w którym znajduje się główna klasa aplikacji, w poszukiwaniu innych klas oznaczonych adnotacjami (np. @Controller – dodamy ją zaraz jako przykład). Dzięki temu Spring Boot "wie", jakie komponenty ma uruchomić.
Zademonstruję, jak dodanie adnotacji @Controller do klasy automatycznie ją importuje (to zaleta IntelliJ) i jak ta adnotacja zmienia zachowanie klasy. Oczywiście, o tym, czym dokładnie jest @Controller, porozmawiamy w kolejnych lekcjach.
Najważniejszy wniosek z tej lekcji jest taki: aby skorzystać z potęgi Spring Boota (automatycznej konfiguracji, skanowania komponentów), wystarczy dodać jedną adnotację @SpringBootApplication do głównej klasy aplikacji.
Na koniec uruchomimy aplikację i pokażę, że serwer Tomcat startuje automatycznie na porcie 8080 – bez żadnej naszej ingerencji w konfigurację. Zobaczymy też błąd, bo jeszcze nie zdefiniowaliśmy, co ma się dziać po wejściu na stronę – ale sam fakt, że serwer działa, to już duży sukces!
Chcesz przejąć pełną kontrolę nad swoją aplikacją Spring Boot? W tej lekcji pokażę Ci, jak to zrobić za pomocą kontrolerów! Dowiesz się, dlaczego są one niezbędne do obsługi żądań przychodzących do Twojego serwera i jak działają jak "kierownicy ruchu", decydując o tym, co się dzieje po wpisaniu adresu w przeglądarce.
Nauczę Cię, jak oznaczyć klasę jako kontroler za pomocą adnotacji @RestController i jak powiązać metody z konkretnymi endpointami i typami żądań (np. GET) za pomocą @GetMapping. Zobaczysz, jak w kilku prostych krokach sprawić, by Twoja aplikacja odpowiadała na żądania i wyświetlała tekst w przeglądarce!
Zrozumiesz fundamentalną rolę kontrolerów w Springu i przygotujesz się do tworzenia bardziej złożonych funkcjonalności.
W tej lekcji pokażę Ci, jak uporządkować Twój kod w Spring Boocie i dlaczego to takie ważne. Zauważymy, że nasza główna klasa aplikacji robi się "bałaganiarska" – odpowiada za zbyt wiele rzeczy naraz. Powinna ona zajmować się tylko uruchamianiem (bootstrapowaniem) aplikacji, a nie obsługą żądań HTTP!
Aby to naprawić, rozdzielimy odpowiedzialności. Stworzymy osobny folder (pakunek) na kontrolery.
Następnie utworzymy nową klasę w tym pakunku – nazwiemy ją UserController. To będzie nasz kontroler odpowiedzialny za obsługę żądań związanych z użytkownikami.
Przeniesiemy do UserController kod, który wcześniej (w poprzedniej lekcji) umieściliśmy w głównej klasie aplikacji – czyli adnotację @RestController i metodę z adnotacją @GetMapping. Dzięki temu nasza główna klasa będzie "czystsza" i skupiona tylko na uruchamianiu aplikacji.
Wyjaśnię, że dzięki magii Spring Boota (a konkretnie dzięki adnotacji @ComponentScan, która jest częścią @SpringBootApplication) nie musimy w żaden sposób "informować" głównej klasy aplikacji o istnieniu UserController. Spring Boot automatycznie wykryje tę klasę, ponieważ znajduje się ona w tym samym pakunku (lub podpakunku) co główna klasa.
Zmodyfikujemy też trochę kod w UserController. Zmienimy nazwę metody na getUsers i endpoint na users, a zwracany tekst na "Lista użytkowników". To tylko kosmetyczne zmiany, żeby kod był bardziej czytelny.
Pamiętaj, aby po każdej zmianie w kodzie zrestartować serwer!
Podsumowując, w tej lekcji nauczysz się, jak organizować kod w projekcie Spring Boot, tworząc osobne pakiety i klasy dla różnych funkcjonalności (np. osobny kontroler dla użytkowników). Dzięki temu Twój kod będzie bardziej przejrzysty, łatwiejszy w utrzymaniu i rozwijaniu.
W tej lekcji pokażę Ci, jak przyspieszyć pracę ze Spring Bootem i uniknąć ciągłego restartowania serwera po każdej zmianie w kodzie. Zrobimy to w dwóch krokach: konfigurując IntelliJ i dodając nową zależność (dependency).
Krok 1: Konfiguracja IntelliJ
Pokażę Ci, jak zmienić ustawienia IntelliJ, aby automatycznie przebudowywał projekt po zmianach. Wchodzimy do ustawień (Settings), wyszukujemy "compiler" i zaznaczamy opcję "Build project automatically". Następnie wchodzimy do "Advanced Settings" i zaznaczamy opcję "Allow auto-make to start even if developed application is currently running". Te zmiany pomogą, ale same w sobie nie wystarczą do pełnej automatyzacji.
Krok 2: Dodanie zależności Spring Boot DevTools
Aby uzyskać pełną automatyzację, dodamy do naszego projektu nową zależność: Spring Boot DevTools. Pokażę Ci, jak to zrobić w pliku pom.xml (plik konfiguracyjny Mavena). Jeśli masz wersję Ultimate IntelliJ, możesz to zrobić za pomocą interfejsu graficznego (klikając "Add Starters"). Jeśli masz wersję Community (lub inny edytor), pokażę Ci, jak ręcznie dodać odpowiedni wpis do sekcji <dependencies> w pliku pom.xml.
Spring Boot DevTools zapewnia szybkie restarty aplikacji (tzw. "live reload"). Dzięki temu, po zapisaniu zmian w kodzie, aplikacja automatycznie się zrestartuje (z niewielkim opóźnieniem) i zobaczysz efekty bez konieczności ręcznego zatrzymywania i uruchamiania serwera.
Zademonstruję, jak to działa w praktyce – po dodaniu DevTools i zmianie ustawień IntelliJ, zmiana tekstu zwracanego przez nasz kontroler (np. z "Lista użytkowników" na "Lista") będzie widoczna w przeglądarce po krótkiej chwili, bez ręcznego restartu. Zwrócę uwagę na to, że restart nie jest natychmiastowy – trzeba chwilę poczekać, aż IntelliJ "zauważy" zmiany i przebuduje projekt (co jest sygnalizowane odpowiednim komunikatem).
Dzięki tej lekcji nauczysz się, jak znacząco przyspieszyć proces tworzenia aplikacji w Spring Boocie, eliminując irytującą konieczność ręcznego restartowania serwera po każdej, nawet najmniejszej, zmianie w kodzie. To praktyczna umiejętność, która przyda Ci się w każdym projekcie Spring Boot!
Jaks tworzyć model? Czym on jest? Co to jest MVC? Co to jest Hibernate?
W tej lekcji zanurzymy się w świat modeli w Spring Boocie! Wyjaśnię, dlaczego są one niezbędne do reprezentowania danych w Twojej aplikacji i jak je tworzyć.
Zauważymy, że w poprzedniej lekcji stworzyliśmy kontroler (UserController), ale tak naprawdę nie zdefiniowaliśmy, czym jest użytkownik dla naszej aplikacji. Dla nas, ludzi, "użytkownik" to ktoś, kto ma imię, nazwę użytkownika, hasło... ale dla komputera to tylko nic nieznaczące słowo!
Model to właśnie sposób na opisanie danych – to taki wzorzec, który mówi, z jakich elementów składa się dany obiekt (np. użytkownik).
Pokażę Ci, jak stworzyć model. Zaczniemy od utworzenia nowego pakunku o nazwie model (analogicznie do pakunku controller z poprzedniej lekcji). W tym pakunku utworzymy nową klasę Java o nazwie User (bez dopisku "Model" – taka jest konwencja).
W klasie User zdefiniujemy pola, które opisują użytkownika:
id (typu Long) – unikalny identyfikator
username (typu String) – nazwa użytkownika
password (typu String) – hasło
firstName (typu String) – imię
Wyjaśnię, dlaczego identyfikator (id) jest tak ważny – pozwala on jednoznacznie zidentyfikować użytkownika, nawet jeśli wielu użytkowników ma takie samo imię czy nazwę użytkownika.
Następnie przejdziemy do kwestii baz danych. Wspomnę o tym, że nie musisz uczyć się SQL-a (języka zapytań do baz danych), żeby korzystać z baz danych w Spring Boocie! Dzięki Hibernate (narzędziu do mapowania obiektowo-relacyjnego) możemy operować na danych za pomocą Javy, a Hibernate zajmie się "tłumaczeniem" tego na język zrozumiały dla bazy danych. Co więcej, Hibernate pozwala na łatwą zmianę typu bazy danych (np. z MySQL na PostgreSQL) bez konieczności modyfikacji kodu Javy!
Aby Hibernate działał poprawnie, musimy spełnić kilka warunków. Pokażę Ci, jak dodać do klasy User:
Pusty konstruktor (bezargumentowy).
Konstruktor przyjmujący wszystkie pola jako argumenty.
Gettery i settery dla wszystkich pól.
Wszystko to zrobimy za pomocą kilku kliknięć w IntelliJ (generowanie kodu).
Na koniec lekcji omówię pokrótce wzorzec MVC (Model-View-Controller). Zauważymy, że tak naprawdę już go używamy!
Model to nasza klasa User – reprezentuje dane.
Controller to nasza klasa UserController – kontroluje przepływ danych i logikę aplikacji.
View (widok) to interfejs użytkownika (np. strona internetowa napisana w React, Vue czy Angular), z którym komunikuje się kontroler.
Podkreślę, że nie musisz na pamięć uczyć się definicji MVC czy Hibernate – ważniejsze jest, żebyś rozumiał, jak to działa w praktyce i potrafił tego używać. Zamiast tracić czas na teorię, skupimy się na praktycznym wykorzystaniu tych narzędzi.
Zapowiem kolejną lekcję, w której połączymy nasz model z prawdziwą bazą danych!
W tej lekcji pokażę Ci, jak zwrócić listę użytkowników w odpowiedzi na żądanie HTTP (czyli jak sprawić, żeby po wejściu na określony adres URL wyświetliła się lista użytkowników).
Zaczniemy od spojrzenia na metodę getUsers w UserController z perspektywy czystej Javy. Przypomnę, że typ zwracany przez metodę (to, co znajduje się przed nazwą metody) określa, co ta metoda ma zwrócić. Skoro chcemy zwrócić listę użytkowników, to musimy zmienić typ zwracany na List<User>.
Następnie, zamiast zwracać pusty String, utworzymy listę (ArrayList) i dodamy do niej kilku przykładowych użytkowników (obiekty klasy User, którą stworzyliśmy w poprzedniej lekcji). Na razie zrobimy to "ręcznie", wpisując dane bezpośrednio w kodzie – później będziemy pobierać te dane z bazy danych.
Na koniec zwrócimy tę listę (za pomocą słowa kluczowego return).
Uruchomimy aplikację i... pojawi się pytanie: w jaki sposób ta lista zostanie wyświetlona w przeglądarce? Przecież lista to struktura danych w Javie, a przeglądarka wyświetla tekst!
I tu wkracza JSON (JavaScript Object Notation). JSON to tekstowy format zapisu danych, oparty na parach klucz-wartość. Jest on powszechnie używany do wymiany danych między serwerem a klientem (np. przeglądarką).
Pokażę Ci, że Spring Boot automatycznie konwertuje naszą listę użytkowników na JSON – dzięki adnotacji @RestController. Nie musimy nic robić – Spring Boot sam "wie", że skoro zwracamy listę, to ma ją zamienić na JSON.
Wyjaśnię, jak wygląda JSON – zobaczysz, że każdy obiekt User jest reprezentowany jako zbiór par klucz-wartość (np. "id": 1, "username": "admin"), a cała lista jest otoczona nawiasami kwadratowymi.
Zwrócę uwagę na to, że JSON to uniwersalny format – dzięki temu, że nasza aplikacja zwraca dane w formacie JSON, każdy klient (napisany w dowolnym języku programowania – Pythonie, JavaScripcie, czymkolwiek!) będzie mógł te dane odczytać i przetworzyć.
Na koniec wspomnę o małym "ale". Domyślnie JSON wyświetlany w przeglądarce może być nieczytelny (jako jeden długi ciąg znaków). Pokażę Ci, jak zainstalować rozszerzenie do przeglądarki Chrome (lub innej opartej na Chromium), które sformatuje JSON i sprawi, że będzie on bardziej czytelny dla człowieka. Link do rozszerzenia dodam do materiałów do lekcji.
Dzięki tej lekcji nauczysz się, jak zwracać złożone dane (listę obiektów) w odpowiedzi na żądanie HTTP i jak Spring Boot automatycznie konwertuje je na uniwersalny format JSON. Zrozumiesz też, dlaczego JSON jest tak popularny w komunikacji między serwerem a klientem.
W tej lekcji pokażę Ci super przydatną funkcję IntelliJ IDEA, która pozwoli Ci testować endpointy (czyli adresy URL Twojej aplikacji) bez konieczności przechodzenia do przeglądarki!
Wystarczy, że klikniesz na zieloną ikonkę strzałki obok definicji endpointu (czyli obok adnotacji @GetMapping w Twoim kontrolerze). Po kliknięciu pojawi się okienko, w którym możesz wysłać żądanie (request) do Twojej aplikacji.
IntelliJ automatycznie wykryje, jakiego typu żądanie obsługuje dany endpoint (w naszym przypadku GET) i wyśle odpowiednie zapytanie.
Po wysłaniu żądania, w dolnej części okna IntelliJ pojawi się podsumowanie:
Informacje o wysłanym żądaniu (typ żądania, adres URL, użyty "agent").
Odpowiedź serwera – w naszym przypadku będzie to tekstowy plik JSON, zawierający listę użytkowników.
Pokażę Ci, że ta odpowiedź jest dokładnie taka sama, jak ta, którą widzieliśmy w przeglądarce. Dzięki temu możesz testować swoje endpointy bezpośrednio w IDE, bez konieczności przełączania się między oknami.
Wyjaśnię, że ta funkcja IntelliJ jest szczególnie przydatna przy bardziej skomplikowanych żądaniach (nie tylko prostych GET-ach).
Co więcej, IntelliJ zapamiętuje wysłane żądania. Możesz je ponownie uruchomić (za pomocą ikonki strzałki w lewym dolnym rogu okna) i porównywać wyniki – np. sprawdzić, jak zmieniła się odpowiedź serwera po wprowadzeniu zmian w kodzie. Dzięki temu nie musisz ręcznie wpisywać adresów URL ani zapamiętywać wyników – wszystko masz pod ręką, w IDE.
Dzięki tej lekcji nauczysz się, jak efektywnie testować swoje endpointy Spring Boot bez opuszczania IntelliJ IDEA, co znacznie przyspieszy i uprzyjemni Twoją pracę.
W tej lekcji zajmiemy się połączeniem naszego modelu User ze Spring Bootem i bazą danych. Wyjaśnię, że na razie nasza klasa User to "zwykła" klasa Java – nie jest ona w żaden sposób powiązana ze Springiem.
Przypomnę, że w przypadku kontrolera (UserController) użyliśmy adnotacji @RestController, która "pochodzi" ze Spring Framework (Spring Boot korzysta ze Spring Framework).
Aby nasz model mógł współpracować z bazą danych, musimy dodać do projektu nową zależność (dependency): Spring Data JPA. Pokażę Ci, jak to zrobić – w pliku pom.xml (plik konfiguracyjny Mavena) dodamy starter o nazwie "JPA".
Wyjaśnię, co to jest JPA (Java Persistence API):
Java – bo działa w ekosystemie Javy.
Persistence – bo dotyczy trwałości danych (zapisu i odczytu z bazy).
API – bo określa interfejs (sposób) pracy z bazą danych.
Mówiąc prościej, JPA to zestaw adnotacji, które pozwolą nam "oznaczyć" nasz model w taki sposób, aby Spring Boot wiedział, jak go używać w kontekście bazy danych.
Wspomnę też o Hibernate – jest to implementacja JPA. JPA definiuje jakie adnotacje są dostępne, a Hibernate jak te adnotacje mają działać w praktyce (czyli jak mają komunikować się z bazą danych). Hibernate "tłumaczy" adnotacje JPA na polecenia zrozumiałe dla konkretnej bazy danych (np. MySQL, PostgreSQL, H2...).
Podkreślę, że jako programiści Javy nie musimy przejmować się szczegółami działania Hibernate – wystarczy, że użyjemy odpowiednich adnotacji JPA, a Hibernate zajmie się resztą.
Dodamy do naszego projektu jeszcze jedną zależność – bazę danych H2. H2 to lekka, wbudowana baza danych, idealna do szybkiego rozpoczęcia pracy (nie wymaga instalacji i konfiguracji zewnętrznego serwera bazy danych). Zaznaczę, że w przyszłości, bez zmiany kodu Javy, będziemy mogli "przesiąść się" na inną bazę danych (np. MySQL, PostgreSQL) – wystarczy zmienić konfigurację i dodać odpowiedni sterownik (dependency). Nie będę zmuszał do instalowania baz, zrobimy to na H2 a potem zmienimy na inne.
Podsumowując: w tej lekcji dodamy do naszego projektu zależności JPA (z Hibernate) i H2, co pozwoli nam w kolejnych lekcjach połączyć nasz model User z bazą danych i zacząć zapisywać i odczytywać dane użytkowników. I to wszystko bez pisania ani jednej linijki kodu SQL – wszystkim zajmie się Spring Data JPA i Hibernate!
W tej lekcji połączymy nasz model User ze Spring Bootem i bazą danych! Pokażę Ci, jak za pomocą kilku prostych adnotacji przekształcić zwykłą klasę Java w encję (entity), którą Hibernate (za pośrednictwem Spring Data JPA) będzie mógł zarządzać w bazie danych.
Zaczniemy od dodania adnotacji @Entity nad definicją klasy User. Wyjaśnię, że słowo "entity" (byt, jednostka) w świecie programowania obiektowego oznacza pojedynczy obiekt, który ma swoją tożsamość i przechowuje dane. Adnotacja @Entity informuje Spring Boot, że ta klasa reprezentuje tabelę w bazie danych.
Zauważysz, że po dodaniu @Entity IntelliJ wyświetli ostrzeżenie (warning) – "No default constructor for entity". Spowodowane brakiem konstruktora.
Następnie zajmiemy się kwestią klucza głównego (primary key). Każda tabela w bazie danych musi mieć kolumnę, która jednoznacznie identyfikuje każdy rekord (wiersz). W naszym przypadku będzie to pole id. Aby oznaczyć je jako klucz główny, dodamy nad nim adnotację @Id. Zobaczysz, że po dodaniu tej adnotacji, obok pola id pojawi się ikonka klucza.
Jednak samo @Id to za mało. Musimy jeszcze określić, w jaki sposób wartość tego pola ma być generowana. Nie chcemy przecież ręcznie przypisywać unikalnych identyfikatorów każdemu nowemu użytkownikowi! Dlatego dodamy kolejną adnotację: @GeneratedValue(strategy = GenerationType.IDENTITY).
@GeneratedValue – informuje, że wartość pola ma być generowana automatycznie.
strategy = GenerationType.IDENTITY – określa strategię generowania. IDENTITY oznacza, że to baza danych zajmie się generowaniem kolejnych, unikalnych wartości (np. poprzez autoinkrementację).
Podkreślę, że dzięki tym adnotacjom nie musimy pisać ani linijki kodu SQL! Hibernate sam, na podstawie adnotacji, "zrozumie", jak stworzyć tabelę w bazie danych, jakie kolumny ma ona zawierać i jak generować wartości klucza głównego.
Podsumowując, w tej lekcji dodamy do klasy User trzy kluczowe adnotacje JPA:
@Entity – aby oznaczyć klasę jako encję (tabelę w bazie danych).
@Id – aby oznaczyć pole id jako klucz główny.
@GeneratedValue(strategy = GenerationType.IDENTITY) – aby określić strategię generowania wartości klucza głównego.
Dzięki temu nasza klasa User stanie się pełnoprawnym modelem, gotowym do współpracy ze Spring Bootem i bazą danych H2. A w następnej lekcji pokażę Ci, jak dodawać, pobierać i modyfikować dane użytkowników!
Dodasz JpaRepository, umożliwiając operacje CRUD bez pisania SQL.
W tej lekcji dowiesz się, czym jest repozytorium w Spring Boocie i dlaczego jest tak ważne.
Przypomnimy sobie, co zrobiliśmy do tej pory:
Stworzyliśmy model User, który opisuje, jak wyglądają dane użytkownika (imię, nazwa użytkownika, hasło, identyfikator).
Za pomocą adnotacji @Entity, @Id i @GeneratedValue połączyliśmy ten model z bazą danych (Hibernate "wie", że ma stworzyć tabelę User w bazie danych).
Model opisuje strukturę danych, ale potrzebujemy jeszcze czegoś, co będzie zarządzać tymi danymi – i tu właśnie wkracza repozytorium.
Repozytorium to, mówiąc najprościej, magazyn danych – taki menadżer, który umożliwia dostęp do bazy danych i wykonywanie na niej operacji (np. pobieranie, dodawanie, usuwanie, modyfikowanie danych).
Pokażę Ci, jak stworzyć repozytorium. Zaczniemy od utworzenia nowego pakunku o nazwie repository (analogicznie do pakunków model i controller). W tym pakunku utworzymy interfejs o nazwie UserRepository (taka jest konwencja – nazwa modelu + "Repository").
Wyjaśnię, że ten interfejs będzie "rozszerzał" (extends) interfejs JpaRepository. To właśnie JpaRepository dostarcza nam za darmo mnóstwo gotowych metod do operowania na danych, np.:
findAll() – pobiera wszystkie rekordy z tabeli.
findById() – pobiera rekord o określonym identyfikatorze.
save() – wstawia nowy rekord lub aktualizuje istniejący.
deleteById() – usuwa rekord o określonym identyfikatorze.
delete() - usuwa podany obiekt
count()- zlicza rekordy
existsById() - sprawdza czy rekord isnieje
...i wiele innych!
Podczas definiowania interfejsu UserRepository musimy określić dwie rzeczy:
Typ modelu, którym to repozytorium ma zarządzać (w naszym przypadku User).
Typ identyfikatora (klucza głównego) w tym modelu (w naszym przypadku Long, bo takie id użyliśmy gdy poprawialiśmy warning).
Zwrócę uwagę na to, że w interfejsie UserRepository nie musimy pisać żadnego kodu! Wystarczy, że rozszerzymy JpaRepository, a Spring Data JPA automatycznie dostarczy nam implementację tych wszystkich metod.
Na koniec wyjaśnię, że repozytorium będziemy wykorzystywać w kontrolerze (UserController). Zamiast bezpośrednio operować na danych w kontrolerze (co byłoby złym rozwiązaniem, bo kontroler powinien zajmować się tylko kontrolą przepływu, a nie zarządzaniem danymi), przekażemy to zadanie repozytorium. Kontroler powie repozytorium: "Pobierz mi wszystkich użytkowników", a repozytorium wykona to polecenie i zwróci dane.
Dzięki tej lekcji zrozumiesz, czym jest repozytorium, jak je stworzyć i dlaczego jest ono tak ważnym elementem w architekturze aplikacji Spring Boot. A w kolejnych lekcjach pokażę Ci, jak korzystać z repozytorium w praktyce!
W tej lekcji pokażę Ci, jak połączyć kontroler (UserController) z repozytorium (UserRepository), aby móc korzystać z metod dostarczonych przez repozytorium (np. findAll(), findById(), save(), delete()).
Wyjaśnię, że normalnie musielibyśmy przekazać instancję repozytorium do kontrolera (np. przez konstruktor), ale Spring Boot oferuje nam prostszy sposób: wstrzykiwanie zależności (dependency injection).
Wstrzykiwanie zależności polega na tym, że Spring Boot automatycznie "dostarcza" (wstrzykuje) potrzebne obiekty (np. repozytorium) do innych obiektów (np. kontrolera).
Aby skorzystać ze wstrzykiwania zależności, wystarczy, że w klasie UserController zrobimy kilka rzeczy:
Stworzymy pole (property) typu UserRepository.
Dodamy konstruktor, który przyjmuje UserRepository jako argument, i przypiszemy argument do naszego pola.
W nowszych wersjach spring można pominiąć adnotacje, ale dla starszych wersji i gdy mamy więcej konstruktorów musimy dodać
Dodamy adnotację @Autowired nad konstruktorem (lub nad polem, jeśli nie używamy konstruktora – to starszy sposób, mniej zalecany).
Adnotacja @Autowired informuje Spring Boot, że ma "wstrzyknąć" instancję UserRepository do tego pola czy też konstruktora.
Dzięki temu wewnątrz metod kontrolera (UserController) będziemy mogli bezpośrednio korzystać z metod repozytorium.
Wyjaśnię, że dzięki temu:
Nie musimy tworzyć instancji UserRepository ręcznie (za pomocą new UserRepository()).
Nie musimy przekazywać UserRepository jako argumentu do metod kontrolera.
Mamy bezpośredni dostęp do metod repozytorium wewnątrz metod kontrolera.
Na koniec napotkamy problem – po uruchomieniu aplikacji zobaczymy błąd. Wyjaśnię, że jest on spowodowany tym, że słowo "user" jest słowem kluczowym (zarezerwowanym) w niektórych bazach danych (np. MySQL). Dlatego nie możemy nazwać naszej tabeli "user".
Aby to naprawić, zmienimy nazwę tabeli, dodając adnotacje @Table(name = "app_users") do naszego modelu, dodatkowo aby uniknać błędów dodamy modyfikator final do pola.
Uruchomimy ponownie i dostaniemy pustą liste.
Po wprowadzeniu tej zmiany aplikacja uruchomi się poprawnie, a my będziemy mogli korzystać z repozytorium w kontrolerze.
Podsumowując, w tej lekcji nauczysz się:
Jak wstrzykiwać zależności (używać @Autowired) w Spring Boocie.
Jak korzystać z repozytorium wewnątrz kontrolera.
Jak rozwiązać problem z nazwą tabeli, która koliduje ze słowem kluczowym w bazie danych.
W jaki sposób dodawać adnotacje aby dostosować nazwe tabeli
W tej lekcji nauczysz się, jak dodawać nowych użytkowników do bazy danych za pomocą metody POST i adnotacji @RequestBody.
Zaczniemy od krótkiego przypomnienia, czym różni się żądanie (request) GET od POST:
GET służy głównie do pobierania danych (np. pobrania listy użytkowników). Wysyłamy je, wpisując adres URL w przeglądarce.
POST służy do wysyłania danych na serwer (np. w celu utworzenia nowego użytkownika). Nie da się go wysłać bezpośrednio z paska adresu przeglądarki – potrzebujemy do tego formularza HTML, skryptu JavaScript, aplikacji mobilnej, narzędzia do testowania API (np. Postman, Insomnia) lub wbudowanego w IntelliJ narzędzia do testowania, lub innego serwera.
Pokażę Ci, jak dodać do kontrolera (UserController) nową metodę, która będzie obsługiwać żądania POST.
Podkreślę, że dzięki Spring Data JPA i Hibernate nie musimy pisać żadnego kodu SQL! Wystarczy, że użyjemy odpowiednich adnotacji (@PostMapping, @RequestBody) i metod z repozytorium (save()), a Spring Boot zajmie się resztą.
Spring Boot automatycznie przekonwertuje ten JSON na obiekt User (pod warunkiem, że nazwy pól w JSON-ie zgadzają się z nazwami pól w klasie User).
Dzięki tej lekcji zrozumiesz:
Czym różni się żądanie GET od POST.
Jak obsługiwać żądania POST w Spring Boocie (za pomocą @PostMapping).
Jak pobierać dane z ciała żądania (za pomocą @RequestBody).
Jak zapisywać nowe dane w bazie danych (za pomocą metody save() z repozytorium).
W tej lekcji pokażę Ci, jak przetestować dodawanie nowych użytkowników (czyli działanie metody addUser z adnotacjami @PostMapping i @RequestBody) za pomocą wbudowanego w IntelliJ narzędzia do testowania API.
Przypomnę, że do wysyłania żądań POST (które służą do wysyłania danych na serwer) nie możemy użyć bezpośrednio paska adresu przeglądarki. Potrzebujemy do tego specjalnego narzędzia. Mogą to być:
Postman
Insomnia
Wbudowane w IntelliJ narzędzie (z którego skorzystamy)
Inne (np. formularz HTML, skrypt JavaScript, aplikacja mobilna)
Pokażę Ci, jak uruchomić to narzędzie w IntelliJ – wystarczy kliknąć zieloną strzałkę obok adnotacji @PostMapping w metodzie addUser.
Wyjaśnię, że w oknie, które się pojawi, musimy zwrócić uwagę na kilka rzeczy:
Typ żądania (Request Method) – musi być ustawiony na POST.
Adres URL – powinien być automatycznie uzupełniony
Content-Type – to bardzo ważne! Musimy ustawić typ zawartości na application json. To informuje serwer, że wysyłamy dane w formacie JSON.
Request Body – tutaj wpisujemy dane użytkownika, którego chcemy dodać, w formacie JSON.
Pokażę Ci, że odpowiedź serwera zawiera dane nowo dodanego użytkownika (w formacie JSON), włącznie z automatycznie wygenerowanym id.
Następnie pokażę Ci, że po odświeżeniu strony w przeglądarce (czyli wysłaniu żądania GET) widzimy nowo dodanego użytkownika na liście.
Zademonstruję, że możemy wielokrotnie wysyłać żądanie POST z tymi samymi danymi – za każdym razem zostanie dodany nowy użytkownik, z kolejnym, automatycznie wygenerowanym id.
Na koniec poruszę kwestię trwałości danych. Zauważymy, że po zrestartowaniu serwera (wyłączeniu i ponownym uruchomieniu aplikacji) wszystkie dodane przez nas dane znikają. Wyjaśnię, że jest to spowodowane tym, że używamy wbudowanej bazy danych H2, która domyślnie przechowuje dane tylko w pamięci – po restarcie dane są tracone. Jest to przydatne do testowania.
Podsumowując, w tej lekcji:
Nauczysz się, jak korzystać z wbudowanego w IntelliJ narzędzia do testowania API.
Dowiesz się, jak wysyłać żądania POST z danymi w formacie JSON.
Przetestujesz działanie metody addUser, dodając nowych użytkowników do bazy danych.
Zrozumiesz, dlaczego dane z bazy H2 znikają po restarcie serwera.
Utrwalisz sobie wiedzę na temat formatu JSON i nagłówka Content-Type
Zobaczysz jak krok po kroku szybko tworzy się aplikacje dzięki Spring Boot, bez zbędnej teorii
W tej lekcji pokażę Ci sztuczkę, która pozwoli Ci ujednolicić nazwy Twoich endpointów i zaoszczędzić trochę pisania. Nauczysz się, jak:
Używać adnotacji @RequestMapping na poziomie kontrolera, aby zdefiniować wspólny prefiks dla wszystkich endpointów w danym kontrolerze.
Dzięki temu skrócić definicje poszczególnych endpointów (np. @GetMapping i @PostMapping).
Szybko zmienić prefiks dla wszystkich endpointów w kontrolerze, modyfikując tylko jedno miejsce w kodzie.
Zrozumiesz lepiej, jak Spring Boot "mapuje" żądania HTTP na konkretne metody w Twoim kontrolerze.
Dzięki tej wiedzy Twój kod stanie się bardziej czytelny i łatwiejszy w utrzymaniu, a Ty zyskasz większą kontrolę nad nazewnictwem swoich endpointów!
W tej lekcji zajmiemy się zabezpieczeniem naszej aplikacji Spring Boot. Pokażę Ci, jak w bardzo prosty sposób dodać podstawowe uwierzytelnianie (logowanie), dzięki któremu dostęp do naszych endpointów będą mieli tylko zalogowani użytkownicy.
Zauważymy, że w tej chwili każdy może wejść na endpoint users i pobrać listę wszystkich użytkowników (wraz z ich danymi!), a także dodawać nowych użytkowników. To oczywiście nie jest bezpieczne!
Aby to zmienić, skorzystamy z modułu Spring Security. Dodamy do naszego projektu nową zależność (dependency): spring-boot-starter-security.
Wyjaśnię, że ta zależność dodaje do naszej aplikacji szereg funkcjonalności związanych z bezpieczeństwem, m.in.:
Uwierzytelnianie (sprawdzanie, czy użytkownik jest zalogowany).
Autoryzacja (sprawdzanie, czy zalogowany użytkownik ma uprawnienia do wykonania określonej akcji).
Obsługa formularza logowania.
Szyfrowanie haseł.
Pokażę Ci, że po dodaniu tej zależności i ponownym uruchomieniu aplikacji (tym razem pełny restart, bo DevTools sobie nie poradzi), przy próbie wejścia na endpoint users zostaniemy przekierowani do strony logowania. Spring Security automatycznie generuje taką stronę!
Wyjaśnię, że Spring Security tworzy też domyślnego użytkownika o nazwie "user" i losowo wygenerowanym haśle. Pokażę Ci, gdzie znaleźć to hasło (w logach aplikacji, w konsoli IntelliJ).
Zalogujemy się, używając tych danych (użytkownik: "user", hasło: wygenerowane hasło). Po zalogowaniu będziemy mieli dostęp do endpointu users i będziemy mogli pobrać listę użytkowników.
Zwrócę uwagę na to, że Spring Security automatycznie obsługuje sesje – po zalogowaniu się, możemy odświeżać stronę i nadal mamy dostęp do chronionych zasobów. Natomiast po otwarciu strony w trybie prywatnym (incognito) sesja się resetuje i musimy zalogować się ponownie.
Podkreślę, że to, co zobaczyliśmy, to podstawowa, domyślna konfiguracja Spring Security. W kolejnych lekcjach nauczymy się, jak ją dostosować do naszych potrzeb (np. jak zdefiniować własnych użytkowników, role, uprawnienia, jak skonfigurować formularz logowania).
Podsumowując, w tej lekcji:
Dodasz do projektu zależność spring-boot-starter-security.
Zobaczysz, jak Spring Security automatycznie zabezpiecza Twoją aplikację, dodając stronę logowania.
Zalogujesz się, używając domyślnego użytkownika i hasła.
Zrozumiesz, że Spring Security oferuje znacznie więcej możliwości, niż tylko podstawowe uwierzytelnianie.
Zobaczysz, że dodanie nowego startera automatycznie zmienia działanie aplikacji.
Dzięki tej lekcji Twoja aplikacja stanie się znacznie bezpieczniejsza, a Ty zyskasz podstawową wiedzę na temat Spring Security!
W tej lekcji połączymy nasz model User ze Spring Security, aby system "wiedział", że to właśnie ta klasa reprezentuje użytkowników, którzy mogą się logować do aplikacji.
Wyjaśnię, że na razie nasza klasa User (mimo że powiązana z bazą danych za pomocą adnotacji JPA) jest dla Spring Security "nieznana". Spring Security nie wie, które pole w tej klasie przechowuje nazwę użytkownika, które hasło, ani jakie role (uprawnienia) mają użytkownicy.
Aby to zmienić, sprawimy, że klasa User będzie implementować interfejs UserDetails (pochodzący ze Spring Security). Ten interfejs definiuje metody, które Spring Security musi "znać", aby móc zarządzać użytkownikami:
getAuthorities() – zwraca kolekcję uprawnień (ról) użytkownika.
getPassword() – zwraca hasło użytkownika.
getUsername() – zwraca nazwę użytkownika.
isAccountNonExpired() – sprawdza, czy konto użytkownika nie wygasło.
isAccountNonLocked() – sprawdza, czy konto użytkownika nie jest zablokowane.
isCredentialsNonExpired() – sprawdza, czy poświadczenia użytkownika (np. hasło) nie wygasły.
isEnabled() – sprawdza, czy konto użytkownika jest aktywne.
Pokażę Ci, że IntelliJ może automatycznie wygenerować implementację tych metod (za pomocą opcji "Implement methods"). Domyślnie metody sprawdzające status konta (cztery ostatnie) zwracają true – czyli zakładamy, że konto jest aktywne, niezablokowane, a poświadczenia nie wygasły. W razie potrzeby moglibyśmy zmodyfikować te metody, aby np. sprawdzać, czy użytkownik aktywował konto przez e-mail.
Skupimy się na metodzie getAuthorities(). Wyjaśnię, że ta metoda ma zwracać kolekcję obiektów implementujących interfejs GrantedAuthority. GrantedAuthority reprezentuje uprawnienie (lub rolę) użytkownika, np. "ADMIN", "USER", "MODERATOR".
Stworzymy nowy typ wyliczeniowy (enum) o nazwie Role, który będzie definiował dostępne role.
Dodamy adnotacje @Enumerated(EnumType.STRING)
Wyjaśnię, dlaczego dodajemy ROLE_ przed nazwa roli.
Następnie dodamy do klasy User nowe pole typu Role, które będzie przechowywać rolę użytkownika.
W metodzie getAuthorities() zwrócimy kolekcję zawierającą jedną rolę użytkownika, opakowaną w obiekt klasy SimpleGrantedAuthority (to prosta implementacja interfejsu GrantedAuthority dostarczana przez Spring Security).
Wyjaśnię, dlaczego dodajemy prefix żeby Spring Security poprawnie interpretował role użytkowników.
Podsumowując, w tej lekcji:
Dowiesz się, czym jest interfejs UserDetails i dlaczego jest ważny dla Spring Security.
Zaimplementujesz interfejs UserDetails w klasie User.
Stworzysz typ wyliczeniowy Role reprezentujący role użytkowników.
Dodasz do klasy User pole role i zaimplementujesz metodę getAuthorities().
Zrozumiesz, jak Spring Security wykorzystuje te informacje do zarządzania użytkownikami i ich uprawnieniami.
Dzięki tym zmianom Spring Security będzie "wiedział", że nasza klasa User reprezentuje użytkowników, którzy mogą się logować do aplikacji, i będzie mógł korzystać z informacji o ich rolach (uprawnieniach).
W tej lekcji wprowadzimy warstwę serwisową do naszej aplikacji Spring Boot. Wyjaśnię, dlaczego jest to dobra praktyka i jak poprawia organizację kodu, szczególnie w miarę rozwoju aplikacji.
Zauważymy, że w tej chwili nasz kontroler (UserController) robi zbyt dużo:
Obsługuje żądania HTTP (GET, POST).
Bezpośrednio wywołuje metody repozytorium (UserRepository), aby operować na danych (np. findAll(), save()).
To nie jest optymalne, ponieważ kontroler powinien zajmować się tylko obsługą żądań i przekazywaniem "roboty" do innych warstw aplikacji. Logika biznesowa (np. walidacja danych, szyfrowanie haseł) powinna być wydzielona do osobnej warstwy – warstwy serwisowej.
Stworzymy nowy pakunek o nazwie service, a w nim klasę UserService. Przeniesiemy do niej pole userRepository (wraz z konstruktorem i adnotacją @Autowired – pamiętając, że to niejawnie dodaje adnotacje) z UserController. Przeniesiemy również metody getUsers i addUser – ale bez adnotacji @GetMapping i @PostMapping, bo te adnotacje są specyficzne dla kontrolera.
Dodamy adnotacje @Service by spring wiedział, że ma używać tej klasy.
Zmodyfikujemy UserController tak, aby korzystał z UserService zamiast bezpośrednio z UserRepository. Pokażę Ci, jak to zrobić szybko i sprawnie za pomocą sztucznej inteligencji (wbudowanej w IntelliJ) – wystarczy zaznaczyć odpowiedni fragment kodu i poprosić AI o refaktoryzację.
Po tych zmianach:
UserController będzie tylko obsługiwał żądania HTTP i delegował zadania do UserService.
UserService będzie zawierał logikę biznesową (na razie tylko wywołania metod repozytorium, ale w przyszłości dodamy tu np. szyfrowanie haseł).
UserRepository będzie wyłącznie odpowiedzialny za komunikację z bazą danych.
Wyjaśnię, że taki podział na warstwy (kontroler, serwis, repozytorium) sprawia, że kod jest bardziej przejrzysty, łatwiejszy w testowaniu i modyfikacji.
Napotkamy problem – po uruchomieniu aplikacji zobaczymy błąd. Wyjaśnię, że jest on spowodowany tym, że Spring Boot nie "widzi" naszej nowej klasy UserService, ponieważ zapomnieliśmy dodać do niej adnotacji @Service. Po dodaniu tej adnotacji wszystko zacznie działać poprawnie.
Podsumowując, w tej lekcji:
Zrozumiesz, czym jest warstwa serwisowa i dlaczego jest ważna.
Stworzysz klasę UserService i przeniesiesz do niej logikę biznesową z kontrolera.
Nauczysz się, jak korzystać ze sztucznej inteligencji do refaktoryzacji kodu.
Dowiesz się, że musisz dodać adnotację @Service, aby Spring Boot "widział" Twoją klasę serwisową.
Zobaczysz, jak Spring Boot automatycznie "wstrzykuje" zależności (np. UserRepository do UserService).
Dzięki tej lekcji Twoja aplikacja będzie miała lepszą architekturę, a Ty zyskasz solidne podstawy do dalszego rozwoju swoich umiejętności w Spring Boocie!
W tej lekcji:
Dowiesz się, jak tworzyć niestandardowe (customowe) metody w repozytorium Spring Data JPA, aby wyszukiwać dane według określonych kryteriów (np. po nazwie użytkownika).
Zobaczysz, że Spring Data JPA potrafi automatycznie generować implementację takich metod na podstawie ich nazw – wystarczy odpowiednio nazwać metodę w interfejsie repozytorium!
Wyjaśnię, dlaczego potrzebujemy metody findByUsername – aby móc zintegrować nasz model User ze Spring Security.
Poznasz interfejs UserDetailsService ze Spring Security i dowiesz się, że musimy zaimplementować jego metodę loadUserByUsername.
Stworzysz metodę findByUsername w interfejsie UserRepository.
Zaimplementujesz metodę loadUserByUsername w klasie UserService, korzystając z metody findByUsername z repozytorium.
Poznasz typ Optional który jest uzywany zamiast zwracania listy lub nulla
Dowiesz się, jak obsługiwać sytuację, gdy użytkownik o podanej nazwie nie zostanie znaleziony (rzucanie wyjątku UsernameNotFoundException).
Zobaczysz, jak używać sugestii (podpowiedzi) IntelliJ do szybkiego generowania kodu.
Poznasz konwencję nazewnictwa metod w Spring Data JPA (np. findBy..., countBy..., existsBy...).
Dowiesz się, jak dodawać dodatkowe warunki do zapytań (np. findByUsernameAndActive).
Pokażę Ci, jak sprawić, by pole username było unikalne w bazie danych (za pomocą adnotacji @Column(unique = true)).
Wyjaśnię Ci, jak Spring Data JPA i Hibernate upraszczają pracę z bazą danych – nie musisz pisać zapytań SQL!
Dzięki tej lekcji:
Nauczysz się tworzyć niestandardowe zapytania do bazy danych za pomocą Spring Data JPA.
Zrozumiesz, jak zintegrować swój model danych ze Spring Security.
Poznasz nowe narzędzia i konwencje, które ułatwiają pracę z Javą i Spring Bootem.
Zobaczysz, jak praktyczna wiedza (np. o konwencjach nazewnictwa) może ułatwić Ci zrozumienie i rozwijanie aplikacji Spring Boot.
W tej lekcji zajmiemy się zabezpieczeniem haseł użytkowników w naszej aplikacji Spring Boot. Wyjaśnię, dlaczego nigdy nie powinniśmy przechowywać haseł w bazie danych w postaci jawnego tekstu (np. "pizza123") i jak użyć PasswordEncodera do zaszyfrowania (zahashowania) haseł przed zapisaniem ich w bazie.
Zauważymy, że w aktualnej implementacji, hasło podane przez użytkownika jest zapisywane w bazie danych bez żadnych zmian. To poważne zagrożenie bezpieczeństwa!
Aby to naprawić, wprowadzimy PasswordEncodera. Wyjaśnię, że PasswordEncoder to interfejs w Spring Security, który definiuje metody do szyfrowania (a właściwie haszowania) haseł. Spring Boot dostarcza gotowe implementacje tego interfejsu, np. BCryptPasswordEncoder.
Podsumowując, w tej lekcji:
Dowiesz się, dlaczego nigdy nie wolno przechowywać haseł w bazie danych w postaci jawnego tekstu.
Poznasz interfejs PasswordEncoder i jego implementację BCryptPasswordEncoder.
Dodasz BCryptPasswordEncoder do swojej klasy UserService.
Zmodyfikujesz metodę addUser, aby haszować hasła przed zapisaniem ich w bazie danych.
Zrozumiesz, jak działa haszowanie haseł i dlaczego jest to kluczowy element bezpieczeństwa aplikacji.
Zobaczysz w jaki sposób zaimplementować PasswordEncodera
Dzięki tej lekcji Twoja aplikacja będzie znacznie bezpieczniejsza, a Ty nauczysz się, jak prawidłowo obsługiwać hasła użytkowników!
W tej lekcji:
Dowiesz się, dlaczego nie powinniśmy tworzyć instancji BCryptPasswordEncoder bezpośrednio w klasie UserService i jak zrobić to w profesjonalny sposób.
Wyjaśnię, czym jest BEAN w Springu i jak działa kontener Springa.
Pokażę Ci, jak stworzyć plik konfiguracyjny w Spring Boocie, używając adnotacji @Configuration.
Nauczysz się, jak zdefiniować metodę zwracającą obiekt, który ma być zarządzany przez Springa jako bean (używając adnotacji @Bean).
Zrozumiesz, jak Spring Boot automatycznie wstrzykuje (inject) zależności (np. PasswordEncodera do UserService) – dzięki temu nie musimy ręcznie tworzyć instancji BCryptPasswordEncoder w UserService.
Zobaczysz, jak uprościć kod, korzystając ze Spring Boot i uniknąć powielania tego samego kodu w wielu miejscach.
Utrwalimy jak działa kontrola przepływu
Zauważymy, że nie zmieniamy UserControllera tylko zajmujemy się logiką biznesową
Podsumowując, w tej lekcji:
Zrozumiesz, czym jest bean i jak działa kontener Springa.
Nauczysz się tworzyć pliki konfiguracyjne w Spring Boocie.
Dowiesz się, jak definiować metody zwracające beany.
Zobaczysz, jak Spring Boot automatycznie wstrzykuje zależności.
Poprawisz architekturę swojej aplikacji, wydzielając konfigurację do osobnego pliku.
Dzięki tej lekcji Twoja aplikacja będzie jeszcze bardziej zbliżona do profesjonalnych standardów, a Ty zyskasz głębsze zrozumienie tego, jak działa Spring Boot!
W tej lekcji skupimy się na zabezpieczeniu naszej aplikacji Spring Boot, a konkretnie na stworzeniu Security Filter Chain. Wyjaśnię, że Security Filter Chain to taki "ochroniarz", który decyduje, kto i na jakich warunkach ma dostęp do poszczególnych endpointów (czyli "pomieszczeń") naszej aplikacji.
Zaczniemy od zmiany nazwy pliku konfiguracyjnego z UserConfig na SecurityConfig. Chcemy, aby wszystkie ustawienia związane z bezpieczeństwem (w tym konfiguracja PasswordEncodera) znajdowały się w jednym miejscu.
Następnie stworzymy w SecurityConfig metodę, która będzie zwracać obiekt typu SecurityFilterChain. To właśnie w tej metodzie zdefiniujemy reguły dostępu do naszych endpointów.
Wyjaśnię, że metoda ta przyjmuje jako argument obiekt typu HttpSecurity. To "główne narzędzie" do konfigurowania reguł bezpieczeństwa.
Pokażę Ci, jak krok po kroku zbudować Security Filter Chain
Pokażę Ci przykładową konfigurację:
Wszystkie żądania (endpointy) – wymagają zalogowania (.anyRequest().authenticated()).
Dodamy formularz logowania
Wyjaśnię, że kolejność definiowania reguł ma znaczenie – Spring Security sprawdza je od góry do dołu i stosuje pierwszą pasującą regułę.
Na koniec wywołujemy metodę .build() na obiekcie HttpSecurity, aby "zbudować" Security Filter Chain i zwracamy go.
Podkreślę, że metoda zwracająca SecurityFilterChain musi być oznaczona adnotacją @Bean – dzięki temu Spring Boot "wie", że ma użyć tej metody do konfiguracji bezpieczeństwa.
Podsumowując, w tej lekcji:
Dowiesz się, czym jest Security Filter Chain i do czego służy.
Stworzysz plik SecurityConfig i zdefiniujesz w nim metodę zwracającą SecurityFilterChain.
Nauczysz się, jak konfigurować reguły dostępu do endpointów za pomocą authorizeHttpRequests(), requestMatchers(), authenticated(), permitAll(), hasRole(), hasAnyRole(), formLogin().
Zrozumiesz, jak działa "łańcuch" filtrów w Spring Security.
Dzięki tej lekcji Twoja aplikacja będzie jeszcze lepiej zorganizowana i zabezpieczona, a Ty zyskasz pełną kontrolę nad tym, kto ma dostęp do jakich zasobów!
W tej lekcji pokażę Ci, jak automatycznie dodawać użytkowników do bazy danych przy starcie aplikacji. To przydatne do celów testowych – dzięki temu nie musimy za każdym razem ręcznie dodawać użytkowników przez formularz.
Wyjaśnię, że nadpisaliśmy domyślny system logowania więc musimy teraz dodać własną logikę.
Zaczniemy od stworzenia nowego pakunku o nazwie init. W tym pakunku stworzymy nową klasę o nazwie DataLoader.
Wyjaśnię, że użyjemy interfejsu CommandLineRunner ze Spring Boot. Ten interfejs definiuje metodę run(), która jest wywoływana po uruchomieniu aplikacji (po zainicjalizowaniu wszystkich binów, kontekstu Springa itp.). To idealne miejsce, aby dodać naszych startowych użytkowników.
Nasza klasa DataLoader będzie implementować interfejs CommandLineRunner i nadpisywać metodę run(). Wewnątrz tej metody umieścimy kod, który doda użytkowników do bazy danych.
Dodatkowo, aby Spring Boot "widział" naszą klasę DataLoader, musimy dodać do niej adnotację @Component.
W metodzie run():
Stworzymy obiekty klasy User, reprezentujące naszych startowych użytkowników (np. admina i zwykłego użytkownika).
Zahashujemy hasła tych użytkowników za pomocą PasswordEncodera (którego "wstrzykniemy" do DataLoader za pomocą konstruktora – tak jak robiliśmy to wcześniej z UserService i UserRepository).
Użyjemy metody save() z UserRepository, aby zapisać użytkowników w bazie danych.
Pokażę Ci, jak przenieść logikę tworzenia użytkownika (ustawianie pól, haszowanie hasła) do osobnej metody – aby kod był bardziej czytelny i łatwiejszy w utrzymaniu.
Zwrócę uwagę na to, że musimy nadać odpowiednie role.
Uruchomimy aplikację i zobaczymy, że po wejściu na endpoint users (po zalogowaniu się) widzimy naszych startowych użytkowników.
Na koniec dodamy prosty warunek, który sprawi, że startowi użytkownicy będą dodawani do bazy danych tylko wtedy, gdy baza jest pusta (czyli przy pierwszym uruchomieniu aplikacji). Użyjemy do tego metody count() z UserRepository.
Podsumowując, w tej lekcji:
Dowiesz się, jak automatycznie dodawać dane do bazy danych przy starcie aplikacji.
Poznasz interfejs CommandLineRunner.
Nauczysz się, jak tworzyć obiekty klasy User i zapisywać je w bazie danych.
Zobaczysz, jak używać PasswordEncodera do haszowania haseł.
Dowiesz się, jak sprawdzić, czy baza danych jest pusta (za pomocą metody count() z repozytorium).
Utrwalisz sobie wiedzę na temat wstrzykiwania zależności (@Autowired), adnotacji @Component i cyklu życia aplikacji Spring Boot.
Zobaczysz, dlaczego warto refaktoryzować kod
Dzięki tej lekcji Twoja aplikacja będzie jeszcze bardziej kompletna i gotowa do testowania, a Ty zyskasz nowe umiejętności, które przydadzą Ci się w każdym projekcie Spring Boot!
W tej lekcji wprowadzimy Thymeleaf – silnik szablonów (template engine) dla Javy, który pozwoli nam tworzyć dynamiczne strony HTML w naszej aplikacji Spring Boot.
Wyjaśnię, że Thymeleaf:
Pozwala na łatwe łączenie kodu HTML z danymi pochodzącymi z backendu (z naszego modelu i kontrolera).
Używa składni zbliżonej do HTML, dzięki czemu jest łatwy do nauczenia się i używania (szczególnie dla osób znających HTML, CSS i JavaScript).
Jest zintegrowany ze Spring Bootem – nie musimy niczego dodatkowo konfigurować.
Podkreślę, że Thymeleaf to tylko jedna z wielu opcji – do tworzenia widoków (frontendu) w Spring Boocie możemy użyć także innych technologii, np. React, Vue, Angular.
Pokażę Ci, jak dodać Thymeleaf do naszego projektu:
Otwieramy plik pom.xml (plik konfiguracyjny Mavena).
Dodajemy nową zależność (dependency): spring-boot-starter-thymeleaf. Możemy to zrobić za pomocą graficznego interfejsu w IntelliJ (klikając "Add Starters") lub ręcznie wpisując odpowiedni fragment kodu w sekcji <dependencies>.
Po dodaniu tej zależności i przebudowaniu projektu (IntelliJ powinien zrobić to automatycznie), Thymeleaf jest gotowy do użycia!
Wyjaśnię że będziemy tworzyć szablony używając HTML i osadzając w nim zmienne i dane.
Podsumowując, w tej lekcji:
Dowiesz się, czym jest Thymeleaf i do czego służy.
Zrozumiesz, że Thymeleaf to jedno z wielu narzędzi do tworzenia widoków w Spring Boocie.
Dodasz zależność spring-boot-starter-thymeleaf do swojego projektu.
Dzięki tej lekcji przygotujesz swoją aplikację do tworzenia dynamicznych stron HTML, a w kolejnej lekcji pokażę Ci, jak używać Thymeleaf w praktyce!
W tej lekcji stworzymy własną, niestandardową stronę logowania do naszej aplikacji Spring Boot, korzystając z Thymeleaf.
Podsumowując, w tej lekcji:
Stworzysz plik login.html – szablon Thymeleaf dla Twojej strony logowania.
Zmodyfikujesz konfigurację Spring Security, aby wskazać własną stronę logowania.
Zrozumiesz, dlaczego potrzebujesz kontrolera do obsługi żądania GET na endpoincie login.
Przygotujesz się do stworzenia kontrolera LoginController w kolejnej lekcji.
Dzięki tej lekcji Twoja aplikacja będzie miała własną stronę logowania (na razie bardzo prostą, ale w kolejnych lekcjach ją rozbudujemy)!
W tej lekcji stworzymy własną stronę logowania do naszej aplikacji Spring Boot, korzystając z Thymeleaf i podstaw HTML-a.
Podsumowując, w tej lekcji:
Stworzysz prosty formularz logowania w HTML.
Dowiesz się, czym są tagi HTML, atrybuty i jak ich używać.
Zrozumiesz, dlaczego token CSRF jest ważny i jak go dodać do formularza za pomocą Thymeleaf.
Przetestujesz działanie swojej nowej strony logowania.
Dzięki tej lekcji Twoja aplikacja będzie miała własną, choć na razie bardzo prostą, stronę logowania, a Ty nauczysz się podstaw HTML-a i dowiesz się, jak zabezpieczyć formularz przed atakami CSRF!
W tej lekcji nadamy naszej stronie logowania ładniejszy wygląd, korzystając z CSS (Kaskadowych Arkuszy Stylów).
Podsumowując, w tej lekcji:
Dowiesz się, czym jest CSS i do czego służy.
Stworzysz plik styles.css i umieścisz w nim kod CSS (możesz skorzystać z gotowego kodu lub wygenerować go za pomocą AI).
Połączysz plik CSS ze swoim plikiem HTML za pomocą tagu <link>.
Zobaczysz, jak niewielka ilość kodu CSS może znacznie poprawić wygląd Twojej strony logowania.
Dzięki tej lekcji Twoja aplikacja będzie nie tylko funkcjonalna, ale i estetyczna, a Ty zrobisz pierwszy krok w kierunku poznania CSS! Pamiętaj, ten kurs nie omawia szczegółów, ale daje Ci podstawy.
Podsumowując, w tej lekcji:
Nauczysz się, jak ograniczać dostęp do endpointów w zależności od roli użytkownika.
Użyjesz metody .hasRole() w konfiguracji SecurityFilterChain.
Zobaczysz, jak Spring Security automatycznie sprawdza uprawnienia użytkownika i blokuje dostęp do chronionych zasobów, jeśli użytkownik nie ma odpowiedniej roli.
Dzięki tej lekcji Twoja aplikacja będzie jeszcze bardziej bezpieczna, a Ty nauczysz się, jak precyzyjnie kontrolować dostęp do poszczególnych endpointów!
Jak stworzyć instrukcje warunkową w Thymeleaf?
W tej lekcji stworzymy model Task (reprezentujący zadanie) i połączymy go z modelem User (reprezentującym użytkownika), aby określić, który użytkownik jest właścicielem danego zadania.
Wyjaśnię, że musimy zdefiniować relację między tabelami tasks i users w bazie danych. Zastanowimy się, jaki typ relacji będzie odpowiedni:
One-to-one (1:1): Jeden użytkownik ma tylko jedno zadanie (i odwrotnie). To raczej nierealistyczne w naszym przypadku.
One-to-many (1:N): Jeden użytkownik ma wiele zadań, ale każde zadanie należy tylko do jednego użytkownika. To brzmi sensownie!
Many-to-many (N:M): Wielu użytkowników może mieć wiele zadań (zadania są współdzielone). To też możliwe, ale na razie skupimy się na prostszym przypadku 1:N.
Wybierzemy relację one-to-many (1:N) – jeden użytkownik może mieć wiele zadań.
Pokażę Ci, jak stworzyć klasę Task w pakunku model:
Dodamy adnotację @Entity, aby oznaczyć klasę jako encję (tabelę w bazie danych).
Zdefiniujemy pola:
id (typu Long) – unikalny identyfikator zadania (z adnotacjami @Id i @GeneratedValue).
title (typu String) – tytuł zadania.
description (typu String) – opis zadania.
user (typu User) – to jest kluczowe! Pole, które będzie przechowywać referencję do obiektu User, czyli do właściciela zadania.
Dodamy adnotacje @ManyToOne oraz @JoinColumn nad polem user:
@ManyToOne – określa, że to jest relacja wiele-do-jednego (wiele zadań może należeć do jednego użytkownika).
@JoinColumn(name = "user_id") – określa nazwę kolumny w tabeli tasks, która będzie przechowywać klucz obcy (foreign key) odwołujący się do klucza głównego (id) w tabeli users.
Dodamy pusty konstruktor (wymagany przez Hibernate).
Dodamy konstruktor przyjmujący jako argumenty tytuł, opis oraz użytkownika
Dodamy gettery i settery dla wszystkich pól.
Dodamy adnotacje @Enumerated(EnumType.STRING)
Przeniesiemy Enum do osobnego pliku
Wyjaśnię, że Spring Data JPA i Hibernate automatycznie obsłużą tworzenie tabeli tasks w bazie danych, łącznie z kolumną user_id i relacją do tabeli users. Nie musimy pisać żadnego kodu SQL!
Podsumowując, w tej lekcji:
Zrozumiesz, czym są relacje między tabelami w bazie danych (one-to-one, one-to-many, many-to-many).
Stworzysz klasę Task reprezentującą zadanie.
Połączysz model Task z modelem User za pomocą adnotacji @ManyToOne i @JoinColumn.
Dowiesz się, jak Spring Data JPA i Hibernate automatycznie obsługują relacje między tabelami.
Utrwalisz sobie wiedzę, o adnotacjach i konstruktorach
Dzięki tej lekcji Twoja aplikacja będzie potrafiła powiązać zadania z użytkownikami, co jest kluczowym elementem systemu do zarządzania zadaniami!
W tej lekcji stworzymy repozytorium dla zadań (TaskRepository) i zdefiniujemy w nim niestandardową metodę do wyszukiwania zadań należących do konkretnego użytkownika.
Podsumowując, w tej lekcji:
Stworzysz interfejs TaskRepository.
Dowiesz się, że TaskRepository automatycznie dziedziczy wiele przydatnych metod z JpaRepository.
Zdefiniujesz niestandardową metodę findByUser(User user) do wyszukiwania zadań po użytkowniku.
Zrozumiesz, jak Spring Data JPA automatycznie generuje implementację metod na podstawie ich nazw.
Utrwalisz sobie wiedzę na temat typów generycznych (List<Task>) i interfejsów.
Dzięki tej lekcji Twoja aplikacja będzie potrafiła wyszukiwać zadania należące do konkretnego użytkownika, co jest kluczowym elementem funkcjonalności systemu do zarządzania zadaniami!
W tej lekcji stworzymy warstwę serwisową dla zadań (TaskService) i zaimplementujemy w niej podstawowe operacje:
Pobieranie zadań danego użytkownika (getTasksForUser).
Dodawanie nowego zadania (addTask).
Usuwanie zadania (deleteTask).
Wyjaśnię, dlaczego logika biznesowa (np. sprawdzanie uprawnień, walidacja danych, szyfrowanie haseł) powinna być umieszczona w warstwie serwisowej, a nie w kontrolerze. Kontroler powinien tylko przyjmować żądania i delegować zadania do serwisu.
Stworzymy klasę TaskService w pakunku service. Dodamy do niej adnotację @Service, aby Spring Boot wiedział, że to jest komponent warstwy serwisowej.
Wstrzykniemy do TaskService repozytorium TaskRepository (za pomocą konstruktora i niejawnej adnotacji @Autowired), aby móc wykonywać operacje na bazie danych.
Zaimplementujemy metodę getTasksForUser(User user
Zaimplementujemy metodę addTask(User user, Task task)
Zaimplementujemy metodę deleteTask(Long taskId, User user).
Wyjaśnię, dlaczego ważne jest sprawdzanie uprawnień przed usunięciem zadania – nie chcemy, aby użytkownik mógł usunąć zadanie, które do niego nie należy!
Pokażę Ci, jak zoptymalizować metodę deleteTask – zamiast dwukrotnie odwoływać się do bazy danych (raz, aby pobrać zadanie, a drugi raz, aby je usunąć), możemy pobrać zadanie tylko raz i usunąć je, używając obiektu, który już mamy.
Podsumowując, w tej lekcji:
Stworzysz klasę TaskService.
Zaimplementujesz w niej metody getTasksForUser, addTask i deleteTask.
Nauczysz się, jak delegować zadania z kontrolera do serwisu.
Zrozumiesz, dlaczego logika biznesowa powinna być umieszczona w warstwie serwisowej.
Dowiesz się, jak sprawdzać uprawnienia użytkownika przed wykonaniem operacji na danych.
Zobaczysz, jak optymalizować kod, unikając niepotrzebnych zapytań do bazy danych.
Dzięki tej lekcji Twoja aplikacja będzie miała kompletną warstwę serwisową do obsługi zadań, a Ty nauczysz się, jak prawidłowo projektować aplikacje Spring Boot!
W tej lekcji dodamy startowe zadania do naszej bazy danych, aby ułatwić sobie testowanie aplikacji. Chcemy, aby te zadania były automatycznie tworzone przy każdym uruchomieniu aplikacji (ponieważ używamy bazy danych H2, która domyślnie działa w pamięci i traci dane po restarcie).
Wykorzystamy do tego stworzoną wcześniej klasę DataLoader (która implementuje interfejs CommandLineRunner – pamiętasz, że jej metoda run() wykonuje się po uruchomieniu aplikacji).
W klasie DataLoader:
Wstrzykniemy repozytorium TaskRepository (za pomocą konstruktora – tak jak robiliśmy to wcześniej z UserRepository i PasswordEncodera).
W metodzie run():
Stworzymy kilka obiektów klasy Task, przypisując im tytuły, opisy i właścicieli (obiekty User – admin i user, które stworzyliśmy wcześniej).
Użyjemy metody save() z TaskRepository, aby zapisać te zadania w bazie danych.
Dodamy warunek by zadania dodawały się tylko gdy nie ma żadnych zadań.
Pokażę Ci, jak skrócić i uprościć kod, korzystając z:
Podpowiedzi (auto-uzupełniania) w IntelliJ IDEA.
Sztucznej inteligencji (AI) – np. możemy zaznaczyć fragment kodu i poprosić AI o jego refaktoryzację lub uzupełnienie.
Zwrócę uwagę na to, że:
Musimy uważać na kolejność argumentów w konstruktorze klasy Task (żeby się nie pomylić!).
Możemy wielokrotnie wywoływać metodę save() z TaskRepository, aby dodać wiele zadań. Możemy też stworzyć listę zadań i użyć saveAll().
Po uruchomieniu aplikacji i zalogowaniu się, zobaczymy, że w bazie danych są już startowe zadania, przypisane do odpowiednich użytkowników.
Podsumowując, w tej lekcji:
Wykorzystasz klasę DataLoader do automatycznego dodawania startowych danych (zadań) do bazy danych.
Utrwalisz sobie wiedzę na temat wstrzykiwania zależności, konstruktorów, metod z repozytorium (save()).
Zobaczysz, jak używać podpowiedzi i AI do przyspieszenia pisania kodu.
Dzięki tej lekcji Twoja aplikacja będzie jeszcze bardziej gotowa do testowania i dalszego rozwoju!
W tej lekcji zajmiemy się kontrolerem dla zadań (TaskController). Stworzymy w nim metody do obsługi żądań HTTP (GET, POST, DELETE) związanych z zadaniami:
Pobieranie zadań danego użytkownika (GET).
Dodawanie nowego zadania (POST).
Usuwanie zadania (DELETE).
odsumowując, w tej lekcji:
Stworzysz klasę TaskController.
Zaimplementujesz w niej metody do obsługi żądań GET, POST i DELETE.
Użyjesz adnotacji @GetMapping, @PostMapping, @DeleteMapping, @RequestBody, @AuthenticationPrincipal i @PathVariable.
Dowiesz się, jak pobierać dane z ciała żądania (request body) i ze zmiennych ścieżki (path variables).
Zrozumiesz, jak Spring Security wstrzykuje obiekt reprezentujący zalogowanego użytkownika.
Utrwalisz sobie wiedzę na temat delegowania zadań z kontrolera do serwisu.
Dzięki tej lekcji Twoja aplikacja będzie potrafiła obsługiwać żądania HTTP związane z zadaniami i wykonywać odpowiednie operacje (pobieranie, dodawanie, usuwanie) – a wszystko to w bezpieczny sposób, z uwzględnieniem zalogowanego użytkownika i jego uprawnień!
W tej lekcji stworzymy widok (stronę HTML) dla listy zadań, korzystając z Thymeleaf. Pokażę Ci, jak:
Wyświetlić listę zadań pobraną z backendu.
Dodać formularz do dodawania nowych zadań.
Dodać przyciski do usuwania zadań.
Obsłużyć komunikaty (np. o poprawnym wylogowaniu, błędzie logowania).
Połączyć widok z kontrolerem (TaskUIController).
Dodać linkowanie do plików CSS
W tej lekcji wprowadzimy aspekty (Aspect-Oriented Programming, AOP) do naszej aplikacji Spring Boot. Wyjaśnię, że aspekty pozwalają nam na wydzielenie pewnych przekrojowych funkcjonalności (takich jak logowanie, śledzenie czasu wykonania metod, obsługa transakcji) z głównej logiki biznesowej aplikacji.
Podsumowując, w tej lekcji:
Dowiesz się, czym są aspekty i do czego służą.
Zrozumiesz, dlaczego warto używać aspektów (aby oddzielić logikę przekrojową od logiki biznesowej).
Dodasz zależność spring-boot-starter-aop do swojego projektu.
Dzięki tej lekcji przygotujesz swoją aplikację do wykorzystania aspektów, a w kolejnych lekcjach pokażę Ci, jak stworzyć własny aspekt i zastosować go do logowania informacji o wywołaniach metod!
W tej lekcji stworzymy i skonfigurujemy nasz pierwszy aspekt w Spring Boocie. Ten aspekt będzie logował informacje o wywołaniach metod w naszej aplikacji.
Podsumowując, w tej lekcji:
Stworzysz klasę LoggingAspect i oznaczysz ją adnotacjami @Aspect i @Component.
Zdefiniujesz w niej metody @Before i @AfterReturning, które będą logować informacje przed i po wywołaniu metod w kontrolerach.
Nauczysz się, jak definiować wyrażenia Pointcut, aby określić, do których metod ma być "doczepiony" aspekt.
Dowiesz się, jak uzyskać dostęp do informacji o wywoływanej metodzie (np. jej nazwy, argumentów, wyniku) za pomocą obiektu JoinPoint.
Zobaczysz, jak Spring AOP pozwala na wydzielenie logiki logowania z głównej logiki aplikacji.
Dzięki tej lekcji Twoja aplikacja będzie automatycznie logować informacje o wywołaniach metod, co ułatwi Ci debugowanie i monitorowanie jej działania! Zobaczysz też, jak prosto można to zrobić za pomocą Spring AOP.
Notatka do lekcji o tworzeniu loggera z pomocą AOP
Chcesz nauczyć się Java Spring Boot, ale nie wiesz, od czego zacząć?
Ten kurs poprowadzi Cię od podstaw aż do poziomu, na którym samodzielnie stworzysz kompletną aplikację.
Bez zbędnej teorii.
Tylko konkretne rozwiązania, które realnie wykorzystuje się w firmach.
Jeśli chcesz budować nowoczesne aplikacje backendowe, pracować w IT lub tworzyć solidne API REST, to jesteś w dobrym miejscu.
"Od razu do mięsa" – praktyka przed teorią
Wiele kursów zaczyna od długich, teoretycznych wstępów, omawiających szczegółowo architekturę Springa, wzorce projektowe (MVC, Dependency Injection) itp.
W moim kursie od razu przechodzę do praktyki, pokazując, jak działa Spring Boot, a dopiero potem wyjaśniam, dlaczego działa w taki, a nie inny sposób. Teoria jest wplatana w praktyczne przykłady, a nie serwowana "na sucho".
Kładę nacisk na zrozumienie dlaczego, a nie tylko jak
Nie tylko pokażę, jak używać poszczególnych adnotacji, metod czy klas, ale też wyjaśnię, dlaczego są one potrzebne, jakie problemy rozwiązują i jak działają "pod spodem". To pozwala na głębsze zrozumienie Spring Boota i uniknięcie bezmyślnego kopiowania kodu.
Stopniowe wprowadzanie złożoności
Nie przytłaczam nadmiarem informacji od samego początku.
Zaczynamy od prostych koncepcji i stopniowo wprowadzamy bardziej zaawansowane zagadnienia (np. najpierw dodajemy użytkowników "na sztywno", a dopiero potem łączymy się z bazą danych; najpierw używamy domyślnej konfiguracji Spring Security, a dopiero potem ją dostosowujemy).
Czego się nauczysz?
Spring Boot od podstaw – nawet jeśli nigdy wcześniej nie korzystałeś z tego frameworka.
Tworzenie API REST – zarządzanie użytkownikami, zadaniami i danymi przy użyciu Spring Boot i Hibernate.
Bezpieczeństwo aplikacji – Spring Security pomogą Ci zabezpieczyć API przed nieautoryzowanym dostępem.
Dla kogo jest ten kurs?
Dla osób znających podstawy Javy, które chcą przejść na wyższy poziom.
Dla programistów, którzy chcą nauczyć się budowania skalowalnych API REST.
Dla każdego, kto chce tworzyć profesjonalne aplikacje backendowe i pracować w branży IT.
Dlaczego warto?
Uczysz się na praktycznym projekcie – krok po kroku budujesz kompletną aplikację.
Zero zbędnej teorii – skupiamy się na realnych wyzwaniach programistycznych.
Przygotowanie do pracy z Spring Boot w produkcji – nie tylko kod, ale też testowanie i wdrażanie.
Nie musisz szukać dodatkowych materiałów – wszystko, czego potrzebujesz, znajdziesz w tym kursie.
Co musisz wiedzieć wcześniej?
Podstawy Javy (klasy, obiekty, interfejsy).
Podstawy JSON i HTTP (jak działa API, GET, POST).
Nie musisz znać Springa – wszystkiego nauczysz się w kursie!
Co zbudujesz?
System zarządzania użytkownikami i zadaniami.
Bezpieczne API z rolami użytkowników.
Bezpieczny system logowania
Co na koniec?
Po kursie masz gotowy projekt do portfolio i realne umiejętności, które możesz wykorzystać w pracy.
Ponad 345 000 studentów uczy się z moich kursów.
Dołącz do nich i naucz się Spring Boot w praktyce!