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
Przykład przez konstruktor:
@Service public class UserService { private final UserRepository repository; public UserService(UserRepository repository) { this.repository = repository; } }
@Component, @Service, @Repository, @Controller)@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(); } }
<beans> <bean id="userService" class="com.example.UserService"/> </beans>
@Component, @Service, …) i Spring sam je wykrywa przez component scanning @Configuration public class AppConfig { @Bean public UserService userService() { return new UserService(userRepository()); } @Bean public UserRepository userRepository() { return new UserRepository(); } }
Spring Boot to framework oparty na Spring, który upraszcza i przyspiesza tworzenie aplikacji Spring.
Spring Boot w IntelliJ IDEA File > New > Project > Spring BootStruktura katalogów:
src/main/java - kod źródłowy aplikacjisrc/main/resources - zasoby (konfiguracja, pliki statyczne)src/test/java - testypom.xml lub build.gradle - konfiguracja budowania
Plik application.properties lub application.yml - konfiguracja 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@Controller lub @RestController@Controller - metody zwracają nazwy widoków w katalogu szablonów @RestController - metody zwracają dane (np. JSON)Spring Boot automatycznie serwuje pliki statyczne z folderów:
src/main/resources/staticsrc/main/resources/publicPliki (HTML, CSS, JavaScript, obrazy) są dostępne bezpośrednio w aplikacji.
Mapowanie nazw widoków na szablony:
src/main/resources/templates.return „users/list”;.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@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); } }
/users/{id}).?page=1&size=10).@Service - oznacza klasę jako usługę biznesową (service layer), zarządzaną przez Spring.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(); } /* ... */ }
application.properties.Przykład:
spring.datasource.url=jdbc:mysql://localhost:3306/mydb spring.datasource.username=root spring.datasource.password=password
save() - tworzenie i aktualizacjafindAll() - pobranie wszystkichfindById() - pobranie po IDdeleteById() - usunięcie po IDdeleteAll() - usunięcie wszystkich obiektówJpaRepository, CrudRepository.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); }
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 konsolijdbc:h2:mem:testdbjdbc:h2:file:./data/testdbspring.datasource.url=jdbc:h2:mem:testdb spring.datasource.username=sa spring.datasource.password= spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true
@Entity.@Column.@Id i strategią generowania klucza głównego (np. @GeneratedValue).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 - klasa reprezentująca odpowiedź HTTP, pozwala na kontrolę nad statusem, nagłówkami i body odpowiedzi.ResponseEntity umożliwia zwracanie różnych statusów HTTP (200 OK, 201 Created, 404 Not Found, itp.) w zależności od wyniku operacji.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 - adnotacja pozwalająca na ustawienie statusu HTTP dla metody lub wyjątku (domyślnie 200 OK).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); }
UserNotFoundException).@ExceptionHandler(klasa_wyjatku.class) obsługuje konkretny typ wyjątku i pozwala na zwrócenie niestandardowej odpowiedzi HTTP.@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"); } }