Ślad: • java_2026_1 • 07_awt • 12_spring

Co to jest Spring Framework

Writing /home/grochu/public_html/wiki/data/cache/c/c69e3f7c7dbd99cf144ad76131e4ffde.i failed
Unable to save cache file. Hint: disk full; file permissions; safe_mode setting.
Writing /home/grochu/public_html/wiki/data/meta/zajecia/java_2026_1/12_spring.meta failed
Unable to save metadata file. Hint: disk full; file permissions; safe_mode setting.
Writing /home/grochu/public_html/wiki/data/cache/7/75e079481936e0d8ade254ee02e13f30.i failed
Writing /home/grochu/public_html/wiki/data/meta/zajecia/java_2026_1/sidebar.meta failed
Writing /home/grochu/public_html/wiki/data/cache/c/c69e3f7c7dbd99cf144ad76131e4ffde.i failed
Unable to save cache file. Hint: disk full; file permissions; safe_mode setting.

REVEAL theme=simple&disableLayout=0&transition=none&controls=1&show_progress_bar=1&build_all_lists=0&show_image_borders=0&horizontal_slide_level=2&enlarge_vertical_slide_headers=0&show_slide_details=1&open_in_new_window=1&size=1024×768

<html> <style type=„text/css”> p { text-align: left;} .reveal { font-size: 30px; } .reveal section { width: 96%; margin: 0 auto; } .reveal .slides { width: 60% !important; } .reveal ul, .reveal ol { margin-left: 1.5em; } .reveal pre code {

height: 100%;
max-height: 100%;
box-sizing: border-box; }

</style> </html>

Spring to zaawansowana platforma do tworzenia aplikacji w Javie. Składa się z wielu modułów wspierających różne aspekty tworzenia aplikacji.

Kluczowym elementem jest kontener IoC (Inversion of Control) udostępniający mechanizm wstrzykiwania zależności (Dependency Injection), co przyspiesza i upraszcza składanie aplikacji.

Spring to „framework frameworków„ - jeden z najpopularniejszych i najbardziej wszechstronnych frameworków w ekosystemie Java.

Strona projektu: spring.io

Spring w IntelliJ IDEA: Spring support in IntelliJ IDEA

Najważniejsze cechy Spring

  • Aspect-Oriented Programming (AOP) - programowanie aspektowe dla obsługi zagadnień przekrojowych (logowanie, obsługa wyjątków, zarządzanie transakcjami, zabezpieczenia)
  • Inversion of Control (IoC) - odwrócenie kontroli nad tworzeniem i zarządzaniem obiektami
  • Dependency Injection (DI) - automatyczne wstrzykiwanie zależności do komponentów

Aspect-Oriented Programming (AOP)

  • AOP to programowanie aspektowe - podejście pozwalające na wydzielenie zagadnień przekrojowych (cross-cutting concerns).
  • Przykłady zagadnień przekrojowych:
    • Logowanie
    • Obsługa wyjątków
    • Zarządzanie transakcjami
    • Zabezpieczenia
  • AOP pozwala na oddzielenie logiki biznesowej od tych zagadnień, co prowadzi do czystszego i bardziej modularnego kodu.

Inversion of Control (IoC)

  • IoC to zasada odwrócenia kontroli nad tworzeniem i zarządzaniem obiektami.
    • Mniejsze sprzężenie między klasami
    • Łatwiejsze testowanie
    • Większa elastyczność i skalowość
  • Tradycyjne podejście: aplikacja sama tworzy obiekty, które potrzebuje.
  • Spring IoC: aplikacja otrzymuje obiekty od kontenera IoC. Kontener zarządza tworzeniem, konfiguracją i niszczeniem obiektów.


IoC - Inversion of Control

Dependency Injection

  • Wstrzykiwanie zależności (DI) to mechanizm, w którym zależności są dostarczane do obiektu z zewnątrz.
  • Sposoby wstrzykiwania:
    • przez konstruktor - zalecane, zapewnia niezmienność i łatwość testowania
    • przez settery - mniej bezpieczne, może prowadzić do niekompletnych obiektów
    • przez pola - najrzadziej stosowane, brak kontroli nad wstrzykiwaniem

Przykład przez konstruktor:

@Service
public class UserService {
    private final UserRepository repository;
 
    public UserService(UserRepository repository) {
        this.repository = repository;
    }
}

Spring - moduły

Podstawowe moduły Spring

  • Spring Core - kontener IoC i wstrzykiwanie zależności
  • Spring Web - aplikacje webowe (Spring MVC)
  • Spring Data - uproszczona praca z bazami danych
  • Spring Security - bezpieczeństwo i autoryzacja
  • Spring AOP - programowanie aspektowe
  • Spring Test - wsparcie dla testów jednostkowych
  • Spring Boot - automatyczna konfiguracja i szybki start

Zalety korzystania ze Spring

  • Gotowe szablony wspierające wiele technologii (JDBC, Hibernate, JPA, itp.)
  • Luźne powiązanie między komponentami - łatwość rozszerzania
  • Łatwość testowania aplikacji dzięki DI
  • Lekkość - wybieramy tylko potrzebne komponenty
  • Szybkość prac developerskich
  • Wysoki poziom abstrakcji
  • Silne wsparcie społeczności i dostawców

Najważniejsze elementy Spring

  • IoC Container - zarządza cyklem życia beanów i wstrzykiwaniem zależności.
  • Bean - obiekt zarządzany przez kontener Spring. Każdy bean ma unikalną nazwę i konfigurację.
  • Bean Scopes - zakresy beanów:
    • Singleton - jedna instancja dla całej aplikacji (domyślny, @Component, @Service, @Repository, @Controller)
    • Prototype - nowa instancja za każdym razem
    • Request - jedna instancja na żądanie HTTP
    • Session - jedna instancja na sesję
  • ApplicationContext - główny interfejs do komunikacji z kontenerem IoC. Dostęp do beanów, obsługa zdarzeń, zasoby.

Cykl życia beanów

  • Tworzenie (instantiation)
  • Konfiguracja właściwości - wstrzykiwanie zależności
  • Inicjalizacja (init method)
  • Użytkowanie
  • Niszczenie (destroy method)

Cykl życia beanów

Adnotacje Spring

@Component - oznacza klasę jako komponent zarządzany przez Spring.

@Service - specjalizacja @Component, oznacza klasę jako usługę biznesową.

@Repository - specjalizacja @Component, oznacza klasę do dostępu do danych.

@Autowired - wstrzykuje zależność (może być na polu, setterze lub konstruktorze).

@Configuration - oznacza klasę, która zawiera definicje beanów.

@Bean - oznacza metodę, która zwraca bean zarządzany przez Spring.

@Configuration
public class AppConfig {  
    @Bean
    public UserService userService() {
        return new UserService(userRepository());
    }
 
    @Bean
    public UserRepository userRepository() {
        return new UserRepository();
    }
}

Konfiguracja Spring

  • XML - plik XML z konfiguracją
      <beans>
        <bean id="userService" class="com.example.UserService"/>
      </beans>
  • Adnotacje - oznaczamy klasy adnotacjami (@Component, @Service, …) i Spring sam je wykrywa przez component scanning
  • konfiguracja w kodzie Java
    @Configuration
    public class AppConfig {
        @Bean
        public UserService userService() {  
            return new UserService(userRepository());
        } 
     
        @Bean
        public UserRepository userRepository() {
            return new UserRepository();
        }
    }

Co to jest Spring Boot

Spring Boot to framework oparty na Spring, który upraszcza i przyspiesza tworzenie aplikacji Spring.

  • Szybkie tworzenie aplikacji - gotowe szablony i konfiguracje
  • Automatyczna konfiguracja - Spring Boot sam konfiguruje wspólne komponenty
  • Wbudowany serwer aplikacji (Tomcat, Netty, Jetty)
  • Prostota - mniej kodu do napisania
  • Produkcyjność - szybki start i iteracyjny rozwój
  • Łatwa integracja z innymi technologiami - gotowe startery
  • Łatwość wdrażania - pojedynczy plik JAR z całą aplikacją

Instalacja i konfiguracja

  • Ręczna konfiguracja projektu Maven lub Gradle z zależnościami Spring Boot
  • Szablon Spring Boot w IntelliJ IDEA
    File > New > Project > Spring Boot
  • Spring Initializer (https://start.spring.io) - narzędzie do generowania szablonu projektu.

Struktura projektu Spring Boot

Struktura projektu Spring Boot

Struktura katalogów:

  • src/main/java - kod źródłowy aplikacji
  • src/main/resources - zasoby (konfiguracja, pliki statyczne)
  • src/test/java - testy
  • pom.xml lub build.gradle - konfiguracja budowania

Plik application.properties lub application.yml - konfiguracja aplikacji.

Tworzenie i uruchamianie aplikacji

Główna klasa aplikacji:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Adnotacja @SpringBootApplication odpowiada za:

  • @Configuration - definiuje klasę jako źródło konfiguracji
  • @EnableAutoConfiguration - włącza automatyczną konfigurację
  • @ComponentScan - szuka komponentów w bieżącym pakiecie

Typowa struktura aplikacji

Warstwy architektoniczne w Spring Boot

Warstwy architektoniczne

  • Presentation Layer (warstwa prezentacji)
    • Obsługa żądań HTTP
    • Kontrolery (@RestController, @Controller)
  • Service Layer (warstwa usług)
    • Logika biznesowa
    • Klasy serwisów (@Service)
  • Data Access Layer (warstwa dostępu do danych)
    • Operacje na bazie danych
    • Repozytoria (@Repository)
  • Domain/Model Layer
    • Encje i modele danych (@Entity)
    • Reguły biznesowe

Spring Boot MVC

  • Model - reprezentacja danych aplikacji, obiekty biznesowe.
    • obiekty Java, encje JPA, DTO
  • View - warstwa prezentacji, widoki
    • HTML, template (Thymeleaf, JSP, FreeMarker)
  • Controller - obsługuje żądania użytkownika, aktualizuje model, wybiera widok.
    • klasy oznaczone @Controller lub @RestController
    • @Controller - metody zwracają nazwy widoków w katalogu szablonów
    • @RestController - metody zwracają dane (np. JSON)

Obsługa plików statycznych

Spring Boot automatycznie serwuje pliki statyczne z folderów:

  • src/main/resources/static
  • src/main/resources/public

Pliki (HTML, CSS, JavaScript, obrazy) są dostępne bezpośrednio w aplikacji.

Mapowanie nazw widoków na szablony:

  • Szablony (Thymeleaf, JSP) umieszczamy w src/main/resources/templates.
  • Metody kontrolera zwracają nazwy szablonów (bez rozszerzenia), np. return „users/list”;.

Kontrolery w Spring MVC

Przykład prostego kontrolera:

@Controller
@RequestMapping("/users")
public class UserController {
 
    @GetMapping
    public String listUsers(Model model) {
        model.addAttribute("users", userService.findAll());
        return "users/list";
    }
 
    @PostMapping
    public String createUser(@ModelAttribute User user) {
        userService.save(user);
        return "redirect:/users";
    }
}

Adnotacje:

  • @Controller - oznacza klasę jako kontroler
  • @RequestMapping - mapuje URL
  • @GetMapping, @PostMapping - mapuje konkretne metody HTTP

Przykład REST API

@RestController
@RequestMapping("/api/")
public class UserRestController {
 
    @GetMapping
    public List<User> getAllUsers() {
        return userService.findAll();
    }
 
    @GetMapping("/users/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.findById(id);
    }
 
    @PostMapping("/users")
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }
 
    @DeleteMapping("/users/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.delete(id);
    }
}

Adnotacje dla REST API

  • @RequestMapping - mapuje URL i metody HTTP
  • @GetMapping, @PostMapping, @PutMapping, @DeleteMapping - wiążą metodę z żądaniem HTTP.
  • @PathVariable - parametry w ścieżce URL (np. /users/{id}).
  • @RequestParam - parametry zapytania (np. ?page=1&size=10).
  • @RequestBody - mapowanie body żądania na obiekt Java.
  • @ResponseBody - konwersja obiektu na JSON.

Services

  • Adnotacja @Service - oznacza klasę jako usługę biznesową (service layer), zarządzaną przez Spring.
  • Oddzielenie logiki biznesowej od warstwy prezentacji i dostępu do danych
  • Interfejsy serwisów - definiują kontrakt (wstrzykiwany do kontrolerów)
interface UserService {
    List<User> findAll();
    User findById(Long id);
    User save(User user);
    void delete(Long id);
}
 
@Service
public class UserServiceImpl implements UserService {  
 
    @Autowired
    private final UserRepository repository;
 
    public List<User> findAll() {
        return repository.findAll();
    }
 
  /* ... */   
}

Łączenie z bazą danych

  • Spring Boot wspiera wiele baz danych (relacyjne i nierelacyjne):
    • MySQL, PostgreSQL, SQLite, H2 (baza w pamięci, do testów), Oracle, Microsoft SQL Server, MongoDB
  • Spring Data JPA (Java Persistence API) - uproszczona praca z bazami danych, automatyczne mapowanie obiektów na tabele, generowanie zapytań SQL, CRUD operacje bez pisania SQL.
  • Automatyczna konfiguracja połączenia z bazą danych na podstawie zależności i ustawień w application.properties.

Przykład:

spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password

Spring Data JPA

  • JPA (Java Persistence API) - standard do mapowania obiektów na bazę danych.
  • Hibernate - najpopularniejsza implementacja JPA.
  • Spring Data JPA - uproszczona praca z JPA.
    • Automatyczne mapowanie obiektów na tabele
    • Automatyczne generowanie zapytań SQL
    • operacje CRUD bez pisania SQL

Aplikacja CRUD

  • CRUD - Create, Read, Update, Delete operacje na bazie danych.
  • Spring Data JPA automatycznie dostarcza metody CRUD:
    • save() - tworzenie i aktualizacja
    • findAll() - pobranie wszystkich
    • findById() - pobranie po ID
    • deleteById() - usunięcie po ID
    • deleteAll() - usunięcie wszystkich obiektów
  • Można definiować własne metody w repozytorium na podstawie konwencji nazewnictwa.

Repozytoria

  • Repozytoria to interfejsy, które Spring Data JPA implementuje automatycznie.
  • Rozszerzają interfejsy takie jak JpaRepository, CrudRepository.
  • Dostarczają gotowe metody do operacji CRUD
  • Możliwość definiowania własnych metod na podstawie konwencji nazewnictwa
    np. findByEmail(String email) wygeneruje zapytanie SQL do wyszukiwania użytkownika po adresie email.

Definicja repozytorium:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    User findByEmail(String email);
}

Konfiguracja połączenia z bazą danych

Ustawienia w application.properties lub application.yml:

  • spring.datasource.url - URL bazy danych
  • spring.datasource.username - nazwa użytkownika
  • spring.datasource.password - hasło
  • spring.jpa.hibernate.ddl-auto - strategia zarządzania schematem bazy danych (create, update, validate, none)
  • spring.jpa.show-sql - wyświetlanie generowanych zapytań SQL w konsoli
  • baza w pamięci H2 (do testów): jdbc:h2:mem:testdb
  • baza w pliku H2: jdbc:h2:file:./data/testdb
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

Encje

  • Encje to klasy reprezentujące dane w bazie danych, oznaczone adnotacją @Entity.
  • Mapowanie pól klasy na kolumny tabeli za pomocą adnotacji @Column.
  • Identyfikator encji oznaczamy adnotacją @Id i strategią generowania klucza głównego (np. @GeneratedValue).
  • @Table(name = „users”) - określa nazwę tabeli w bazie danych, aby uniknąć konfliktów z zarezerwowanymi słowami (np. User).
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
 
    @Column(nullable = false, unique = true)
    private String email;
 
    @Column(nullable = false)
    private String name;
}

ResponseEntity

  • ResponseEntity - klasa reprezentująca odpowiedź HTTP, pozwala na kontrolę nad statusem, nagłówkami i body odpowiedzi.
  • Użycie ResponseEntity umożliwia zwracanie różnych statusów HTTP (200 OK, 201 Created, 404 Not Found, itp.) w zależności od wyniku operacji.
  • Builder: ResponseEntity.status(HttpStatus.OK).headers(headers).body(body) - tworzenie odpowiedzi z określonym statusem, nagłówkami i ciałem.
@GetMapping("/users/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
    User user = userService.findById(id);
    if (user != null) {
        return ResponseEntity.ok(user);
    } else {
        return ResponseEntity.notFound().build();
    }
}

ResponseStatus

  • @ResponseStatus - adnotacja pozwalająca na ustawienie statusu HTTP dla metody lub wyjątku (domyślnie 200 OK).
  • Wyjątek ResponseStatusException - pozwala na rzucanie wyjątków z określonym statusem HTTP i komunikatem.

Jest on zamieniany na odpowiednią odpowiedź HTTP przez Spring.

@ResponseStatus(HttpStatus.NO_CONTENT)
@DeleteMapping("/users/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Integer id) {
    User user = userService.findById(id);
    if (user == null) {
        throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found: " + id);
    }
    userService.deleteUser(id);
}

Obsługa błędów w REST API

  • Obsługa błędów w logice biznesowej realizuje się w serwisie przez rzucanie wyjątków (np. UserNotFoundException).
  • Kontroler może obsługiwać te wyjątki i zwracać odpowiednie statusy HTTP (np. 404 Not Found).
  • Metoda @ExceptionHandler(klasa_wyjatku.class) obsługuje konkretny typ wyjątku i pozwala na zwrócenie niestandardowej odpowiedzi HTTP.
  • Klasa oznaczona @ControllerAdvice lub @RestControllerAdvice pozwala na centralne zarządzanie obsługą wyjątków w całej aplikacji.
@RestControllerAdvice
public class GlobalExceptionHandler {
 
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<String> handleNotFound(
            ResourceNotFoundException ex) {
        return ResponseEntity
            .status(HttpStatus.NOT_FOUND)
            .body(ex.getMessage());
    }
 
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleGeneral(Exception ex) {
        return ResponseEntity
            .status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body("Błąd serwera");
    }
}

Dokumentacja