Spring

Baza pytań rekrutacyjnych i wiedzy. Filtruj, szukaj i sprawdzaj swoją wiedzę.

Tematy
easydiinversion-of-controlspring+1

Odpowiedź

Dependency Injection polega na tym, że obiekt dostaje swoje zależności z zewnątrz (zwykle przez konstruktor), zamiast tworzyć je sam przez new. W Springu kontener IoC tworzy beany, wstrzykuje zależności i zarządza cyklem życia, zmniejszając coupling i ułatwiając testowanie.

@Service
class UserService(private val userRepository: UserRepository) {
    fun getUser(id: Long): User {
        return userRepository.findById(id).orElseThrow()
    }
}
mediumannotationconfigurationbean+1

Odpowiedź

@Component oznacza klasę wykrywaną przez component scanning i automatycznie rejestrowaną jako bean. @Bean stosuje się na metodzie w klasie @Configuration, aby obiekt zwrócony przez metodę stał się beanem — zwykle dla typów z bibliotek zewnętrznych lub niestandardowej inicjalizacji. W obu przypadkach powstaje zarządzany bean Springa.

easyspring-bootdependencyconfiguration

Odpowiedź

Startery to przygotowane zestawy zależności, które dodają typowe biblioteki (z kompatybilnymi wersjami) dla danej funkcji. Np. spring-boot-starter-web dociąga Spring MVC, Jackson i wbudowany serwer. Ułatwiają start i współpracują z auto‑konfiguracją.

mediumbeanscopelifecycle+1

Odpowiedź

Zakres beana (scope) określa jego cykl życia i zasięg. Domyślnie jest singleton (jedna instancja w kontenerze). Prototype tworzy nową instancję przy każdym wstrzyknięciu. W aplikacjach webowych są też scope’y request, session i application.

hardtransactionaopdatabase+1

Odpowiedź

@Transactional działa przez proxy/AOP Springa: przed wejściem do metody otwierana jest transakcja, a po wyjściu następuje commit lub rollback zgodnie z wyjątkami i regułami. Można ustawić propagację i izolację; wywołanie metody z tej samej klasy omija proxy.

Odpowiedź

Spring tworzy obiekty (beany) i wstrzykuje im zależności, więc kod nie skleja wszystkiego ręcznie. Wstrzykiwanie przez konstruktor jest jawne, wspiera niemutowalność (`final`) i jest najłatwiejsze do testowania.

@Service
class UserService {
  private final UserRepository repo;

  UserService(UserRepository repo) {
    this.repo = repo;
  }
}

Odpowiedź

Wszystkie to „stereotypy” do component scan; różnica to głównie intencja. `@Service` oznacza logikę biznesową, `@Repository` warstwę dostępu do danych i może tłumaczyć wyjątki persystencji, a `@Component` jest ogólne.

easyrestcontrollercontrollerspring-mvc

Odpowiedź

`@RestController` to w praktyce `@Controller` + `@ResponseBody`, więc metody zwracają bezpośrednio body odpowiedzi (często JSON). `@Controller` zwykle służy do widoków/template’ów renderowanych po stronie serwera.

Odpowiedź

`singleton` (domyślnie) oznacza jedną instancję beana na kontener Springa. `prototype` oznacza nową instancję przy każdym pobraniu; w aplikacjach web są też scope request/session.

Odpowiedź

Uruchamia metodę w transakcji; domyślnie Spring robi rollback na unchecked (`RuntimeException`). Typowa pułapka to self-invocation: wywołanie `@Transactional` z tej samej klasy omija proxy, więc transakcja może się nie uruchomić.

@Service
class PaymentService {
  @Transactional
  public void pay() {
    // DB writes here
  }
}
mediumspring-bootauto-configurationstarter

Odpowiedź

Boot auto-konfiguruje beany na podstawie zależności na classpath i properties (daje sensowne defaulty). Startery to paczki zależności (np. `spring-boot-starter-web`), które dobierają biblioteki i uruchamiają powiązaną auto-konfigurację.

Odpowiedź

Spring AOP zwykle działa przez proxy wokół beana. Gdy metoda w tej samej klasie wywoła inną „aspektowaną” metodę bezpośrednio (`this.someMethod()`), omija proxy, więc np. `@Transactional` może się nie zadziałać.

hardcontrolleradviceexceptionhandlererror-handling

Odpowiedź

Użyj `@ControllerAdvice` z `@ExceptionHandler`, aby mapować wyjątki na spójne odpowiedzi HTTP (status + body). Dzięki temu kontrolery są czystsze, a obsługa błędów jest w jednym miejscu.

@ControllerAdvice
class ApiErrors {
  @ExceptionHandler(IllegalArgumentException.class)
  ResponseEntity<String> badRequest(IllegalArgumentException e) {
    return ResponseEntity.badRequest().body(e.getMessage());
  }
}

Odpowiedź

Głównie w łańcuchu filtrów bezpieczeństwa, zanim request trafi do kontrolera. Filtry budują `SecurityContext` (authentication), a potem reguły autoryzacji decydują o dostępie (URL, method security itd.).

Odpowiedź

`@WebMvcTest` to test typu slice: ładuje warstwę MVC (kontrolery itd.) i jest szybki, zwykle z mockami zależności. `@SpringBootTest` ładuje cały kontekst aplikacji i nadaje się do integracji, ale jest wolniejszy.

easyconfigurationbeanspring-core

Odpowiedź

`@Configuration` oznacza klasę, w której definiujesz beany Springa. `@Bean` oznacza metodę, której wynik ma być zarządzany przez Spring jako bean (tworzenie, wstrzykiwanie, lifecycle).

@Configuration
class AppConfig {
  @Bean
  Clock clock() {
    return Clock.systemUTC();
  }
}
mediumspring-mvcrequestparampathvariable+1

Odpowiedź

`@PathVariable` używaj do identyfikatorów będących częścią ścieżki zasobu (np. `/users/{id}`). `@RequestParam` jest dla opcjonalnych filtrów, paginacji i parametrów zapytania (np. `?page=2&sort=name`).

@GetMapping("/users/{id}")
UserDto getUser(@PathVariable String id, @RequestParam(defaultValue = "false") boolean verbose) {
  return service.get(id, verbose);
}
mediumvalidationbean-validationjakarta+1

Odpowiedź

`@Valid` uruchamia Bean Validation (Jakarta Validation) na podstawie adnotacji typu `@NotNull`, `@Size` dla body/parametrów. Walidacja działa po stronie serwera, zanim kontroler przetworzy obiekt; błędy zwykle kończą się 400 (często przez exception handler).

Odpowiedź

N+1 to sytuacja, gdy pobierasz N encji nadrzędnych, a potem leci po jednym dodatkowym zapytaniu na każdą (lazy loading). Ograniczasz przez fetch join, `@EntityGraph`, batching albo lepsze zapytania, żeby zmniejszyć liczbę round-tripów.

Odpowiedź

`REQUIRED` oznacza: dołącz do istniejącej transakcji, jeśli jest; w przeciwnym razie rozpocznij nową. To domyślne ustawienie, bo dobrze się składa w typowych wywołaniach serwis→serwis.

easyprofilesconfigurationspring

Odpowiedź

`@Profile` warunkowo włącza beany w zależności od aktywnego profilu (np. `dev`, `test`, `prod`). Pozwala podmieniać implementacje/konfigurację per środowisko bez zmiany kodu.

Odpowiedź

Gdy masz wiele instancji, każda uruchomi ten sam job i powstaną duplikaty. Unikasz tego przez leader election, distributed lock (ostrożnie), jedną dedykowaną instancję schedulera albo przeniesienie schedulowania do systemu zewnętrznego.

Odpowiedź

`Page` zawiera total count i liczbę stron (wymaga dodatkowego zapytania count). `Slice` wie tylko, czy jest następna strona (bez total count), więc jest tańszy. Użyj `Slice`, gdy nie potrzebujesz sum i chcesz lepszej wydajności.

Odpowiedź

Spring uruchamia metodę na osobnym executorze przez proxy. Typowa pułapka to self-invocation (wywołanie z tej samej klasy), które omija proxy, więc metoda nie poleci async. Ważne jest też odpowiednie ustawienie executora.

Odpowiedź

SecurityContext jest często trzymany w ThreadLocal. Gdy zmieniasz wątek (async/executor), nowy wątek może nie mieć tego kontekstu i znika info o użytkowniku. Trzeba propagować kontekst albo użyć wspieranej integracji bezpieczeństwa dla async.

Odpowiedź

`ApplicationContext` to kontener IoC Springa: tworzy, łączy i zarządza beanami (wraz z ich cyklem życia) oraz pozwala je wyszukiwać po typie/nazwie.

Odpowiedź

`@ConfigurationProperties` bindowuje grupę wartości konfiguracyjnych do typowanej klasy, więc łatwiej to walidować, refaktorować i testować. Utrzymuje konfigurację w strukturze (jeden prefix) i nie rozrzuca stringowych kluczy po całym kodzie.

Odpowiedź

`@PostConstruct` uruchamia się po utworzeniu beana i wstrzyknięciu zależności. `@PreDestroy` uruchamia się przy zamykaniu kontekstu aplikacji (dla beanów, którymi zarządza, zwykle singletonów). Częsty gotcha: Spring nie wywołuje automatycznie destruktorów dla beanów w scope `prototype`.

Odpowiedź

`BeanPostProcessor` to hook, który może modyfikować lub owijać beany przed/po inicjalizacji. Spring używa go m.in. do AOP proxy, `@Async` i `@Transactional`. Przydaje się do zachowań przekrojowych, ale to “mocna broń”, którą łatwo nadużyć.

Odpowiedź

Spring MVC jest oparte o servlet i zwykle używa wątku na request; jest świetne dla większości CRUD i dobrze współpracuje z blokującymi bibliotekami. WebFlux jest reaktywne i non-blocking, co pomaga przy dużej współbieżności i streamingu — ale tylko jeśli cały stack jest non-blocking. WebFlux z blokującymi wywołaniami często zabiera korzyści.

Odpowiedź

`@RequestBody` mapuje body requestu (zwykle JSON) na obiekt przez `HttpMessageConverter` (często Jackson). Częsty problem to brak lub zły `Content-Type: application/json`, co może skończyć się błędami 415/400. Możesz połączyć z `@Valid`, żeby walidować input.

Odpowiedź

Actuator dodaje endpointy operacyjne jak health checki, metryki i info (np. `/actuator/health`, `/actuator/metrics`). Pomaga w monitoringu i debugowaniu, ale może ujawniać wrażliwe dane (env, konfigurację, szczegóły systemu), więc trzeba ograniczyć dostęp i wystawiać tylko to, co potrzebne.

Odpowiedź

Na wysokim poziomie: bardziej “specyficzne” źródła nadpisują defaulty. Argumenty z linii poleceń i zmienne środowiskowe zwykle nadpisują `application.yml`, a konfiguracja profilu (np. `application-prod.yml`) nadpisuje bazową, gdy profil jest aktywny. Spring składa wartości z wielu źródeł i wygrywa to o wyższym priorytecie.

Odpowiedź

`@Cacheable` zapisuje wynik wywołania metody pod kluczem (zwykle z argumentów). Jest realizowane przez proxy/AOP. Typowe pułapki: self-invocation omija proxy (cache nie zadziała) oraz ryzyko “starych” danych, jeśli nie robisz invalidacji (`@CacheEvict`) lub TTL po stronie dostawcy cache.

Odpowiedź

`isolation` mapuje się na poziom izolacji w bazie (jak współbieżne odczyty/zapisy na siebie wpływają). `readOnly = true` to zwykle hint dla frameworka/drivera do optymalizacji, ale nie zawsze blokuje zapisy “z automatu”. I pamiętaj: `@Transactional` działa przez proxy, więc nie zadziała przy self-invocation.

mediumspring-bootauto-configurationstarters+1

Odpowiedź

Spring Boot używa `@EnableAutoConfiguration` oraz adnotacji warunkowych, aby konfigurować beany na podstawie classpath i właściwości (np. `@ConditionalOnClass`, `@ConditionalOnProperty`). Startery dostarczają zależności, a auto‑config tworzy rozsądne domyślne beany, które możesz nadpisać.

Odpowiedź

`@ConfigurationProperties` jest lepsze do wiązania grup powiązanych ustawień w jeden obiekt — wspiera zagnieżdżenia i walidację oraz trzyma konfigurację spójnie. `@Value` nadaje się do pojedynczych wartości, ale gorzej sprawdza się przy większych konfiguracjach.

@ConfigurationProperties(prefix = "app")
public class AppProps {
  private String name;
  public String getName() { return name; }
  public void setName(String name) { this.name = name; }
}

Odpowiedź

`@Profile` włącza lub wyłącza beany zależnie od aktywnego profilu (np. `dev`, `test`, `prod`). Używaj go do konfiguracji specyficznych dla środowiska: mocków, innych data source, itp.

Odpowiedź

`@Primary` wskazuje domyślny bean, gdy jest wiele kandydatów. `@Qualifier` pozwala wybrać konkretny bean po nazwie/kwalifikatorze w miejscu wstrzyknięcia. Możesz je łączyć: `@Primary` jako domyślne i `@Qualifier` tam, gdzie chcesz nadpisać.

Odpowiedź

`@RestController` to `@Controller` + `@ResponseBody`, więc wartości zwracane są zapisywane w odpowiedzi HTTP (zwykle JSON). `@Controller` służy do widoków MVC i zwykle zwraca nazwę widoku, chyba że dodasz `@ResponseBody`.

Odpowiedź

`@PostConstruct` uruchamia się po wstrzyknięciu zależności, aby wykonać inicjalizację (np. walidacja konfiguracji, rozgrzanie cache). `@PreDestroy` działa przy zamykaniu kontekstu, aby zwolnić zasoby. To hooki lifecycle zarządzane przez kontener.

Odpowiedź

`@Async` uruchamia metodę w osobnym wątku przez proxy Springa i `Executor`. Typowe pułapki: nie działa przy self‑invocation, wymaga publicznej metody na beanie Springa i blokujące I/O może zajechać pulę wątków, jeśli nie jest dobrze ustawiona.

Odpowiedź

fixedRate planuje kolejne uruchomienie względem startu poprzedniego (może się nakładać, jeśli zadanie trwa długo). fixedDelay planuje względem zakończenia poprzedniego (bez nakładania). cron używa wyrażeń cron do harmonogramów kalendarzowych.

Odpowiedź

WebClient to nowszy, nieblokujący klient reaktywny (dobry do WebFlux i async IO). RestTemplate jest blokujący i jest w trybie maintenance. W nowym kodzie zwykle preferuj WebClient, chyba że świadomie chcesz zachowania blokującego.

Odpowiedź

BeanFactory to minimalny kontener IoC (domyślnie lazy). ApplicationContext rozszerza go o funkcje typu i18n, eventy i eager inicjalizację singletonów. W praktyce zwykle używa się ApplicationContext.