Co to jest Spring Framework
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.
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; } }
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)
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 Bootw IntelliJ IDEA
File > New > Project > Spring Boot - Spring Initializer (https://start.spring.io) - narzędzie do generowania szablonu projektu.
Struktura projektu Spring Boot
Struktura katalogów:
src/main/java- kod źródłowy aplikacjisrc/main/resources- zasoby (konfiguracja, pliki statyczne)src/test/java- testypom.xmllubbuild.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
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
@Controllerlub@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/staticsrc/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 aktualizacjafindAll()- pobranie wszystkichfindById()- pobranie po IDdeleteById()- usunięcie po IDdeleteAll()- 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 danychspring.datasource.username- nazwa użytkownikaspring.datasource.password- hasłospring.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ą
@Idi 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
ResponseEntityumoż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
@ControllerAdvicelub@RestControllerAdvicepozwala 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
- Oficjalna dokumentacja Spring: Spring Framework Documentation
- Oficjalna dokumentacja Spring Boot: Spring Boot Documentation
- Przykłady i tutoriale: Spring Guides






