Spring Boot — podstawy
Spring Boot to standard budowy serwisów Java w ProfessNet. Daje gotowy kontener DI, serwer aplikacyjny i autokonfigurację. Ta lekcja pokazuje podstawowe wzorce: warstwy, kontrolery, wstrzykiwanie i konfigurację.
Warstwy
Serwis Spring Boot dzielimy na warstwy o jasnych odpowiedzialnościach:
controller → service → repository → baza danych
(HTTP) (logika) (dostęp do danych)
Standard ProfessNet: kontroler nie zawiera logiki domenowej — waliduje wejście, woła
servicei zwraca odpowiedź. Logika żyje w@Service, dostęp do danych w@Repository.
Kontroler REST
@RestController
@RequestMapping("/api/v1/inventory")
public class InventoryController {
private final InventoryService service;
public InventoryController(InventoryService service) {
this.service = service;
}
@PostMapping("/scan")
@ResponseStatus(HttpStatus.ACCEPTED)
public ScanResult scan(@Valid @RequestBody ScanRequest request) {
return service.runScan(request.forest());
}
}
Wstrzykiwanie przez konstruktor
Zależności wstrzykujemy przez konstruktor, a pola robimy final. Unikamy
@Autowired na polach — utrudnia testowanie i ukrywa zależności.
// dobrze — constructor injection, pola final
@Service
public class InventoryService {
private final ProbeRepository repository;
public InventoryService(ProbeRepository repository) {
this.repository = repository;
}
}
// źle — field injection
@Service
public class BadService {
@Autowired private ProbeRepository repository; // trudne do testów
}
Standard ProfessNet: constructor injection zawsze. Spring od wersji 4.3 wstrzykuje automatycznie, gdy klasa ma jeden konstruktor —
@Autowirednie jest potrzebne.
Walidacja wejścia
DTO walidujemy adnotacjami Bean Validation. @Valid w kontrolerze uruchamia
walidację, a błędy stają się czytelnym 400.
public record ScanRequest(
@NotBlank @Size(max = 255) String forest,
boolean deep) {}
DTO jako record
Do przenoszenia danych używamy record — niezmienne, zwięzłe, bez boilerplate.
public record ScanResult(String jobId, String forest, Instant enqueuedAt) {}
Konfiguracja
Ustawienia trzymamy w application.yml, a sekrety wstrzykujemy ze zmiennych
środowiskowych — nigdy nie zaszywamy ich w kodzie.
spring:
datasource:
url: ${DB_URL}
username: ${DB_USER}
password: ${DB_PASSWORD}
zeus:
scan:
max-concurrency: 10
Typowane właściwości wstrzykujemy przez @ConfigurationProperties:
@ConfigurationProperties(prefix = "zeus.scan")
public record ScanProperties(int maxConcurrency) {}
| Adnotacja | Rola |
|---|---|
@RestController | warstwa HTTP, zwraca JSON |
@Service | logika domenowa |
@Repository | dostęp do danych |
@Valid + Bean Validation | walidacja DTO |
@ConfigurationProperties | typowana konfiguracja |
Wskazówka: sekrety (
DB_PASSWORD) zawsze przez${ENV}. W repo trzymamyapplication.ymlbez wartości sekretnych — te dostarcza środowisko.
Czysty podział na warstwy, constructor injection, walidacja DTO i konfiguracja poza kodem — to fundament każdego serwisu Spring Boot w ProfessNet. Na tej bazie budujemy obsługę wyjątków, logowanie i testy.