Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
---
layout: post
title: "Czy wiesz, że zależności w Springu powinniśmy wstrzykiwać przez konstruktor?"
date: 2026-02-12T08:00:00+01:00
published: true
didyouknow: false
lang: pl
author: bpietrowiak
image: /assets/img/posts/2026-03-06-czy-wiesz-ze-zaleznosci-w-springu-powinnismy-wstrzykiwac-przez-konstruktor/thumbnail.webp
description: "Poznaj zalety tego podejścia, przykłady kodu i wskazówki dotyczące testowania oraz bezpieczeństwa aplikacji."
tags:
- spring boot
- java
---

Czy wiesz, że sposób wstrzykiwania zależności w Springu może mieć ogromny wpływ na jakość Twojego kodu, jego bezpieczeństwo i łatwość testowania?
Jeśli chcesz pisać lepsze aplikacje, warto poznać najważniejsze techniki i wybrać tę, która naprawdę robi różnicę.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tę, która przynosi najlepsze efekty?
ewentualnie jakaś konkretna korzyść, np.:

  • tę, która zagwarantuje Twojej aplikacji najwyższą odporność na błędy.
  • która maksymalnie uprości późniejszy rozwój i utrzymanie Twojego systemu.
  • która znacznie skróci czas pisania testów jednostkowych i poprawi czytelność architektury.


## Czym jest wstrzykiwanie zależności?

Wstrzykiwanie zależności (ang. *Dependency Injection*, DI) w Springu to kluczowy mechanizm,
który umożliwia automatyczne zarządzanie zależnościami pomiędzy obiektami w aplikacji.
Jest to część szerszego podejścia do programowania, znanego jako *Inversion of Control* (IoC),
w którym zarządzanie tworzeniem obiektów i ich zależnościami przekazywane jest z aplikacji do kontenera IoC (w Springu jest nim Spring Container).

## Metody wstrzykiwania zależności

Możemy wyróżnić kilka sposobów wstrzykiwania zależności, z których każdy ma swoje zalety i ograniczenia.
Poniżej przedstawiam najpopularniejsze techniki DI:

- Wstrzykiwanie przez konstruktor z jawnie zdefiniowanym konstruktorem
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stylistyka: "Wstrzykiwanie jawnie zdefiniowanym konstruktorem"

```java
@Component
public class ServiceA {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

luźna sugestia. ServiceA, ServiceB nic nie znaczą, dlatego zawsze namiawiam, żeby w przykładach używać realistycznych nazw - taki kod jest wtedy bardziej czytelny.
Na przykład OrderService do którego wstrzykujemy PaymentService.

private final ServiceB serviceB;

public ServiceA(final ServiceB serviceB) {
this.serviceB = serviceB;
}
}
```

- Wstrzykiwanie przez konstruktor z wykorzystaniem adnotacji `@RequiredArgsConstructor`
```java
@Component
@RequiredArgsConstructor
public class ServiceA {
private final ServiceB serviceB;
}
```
*Adnotacja `@RequiredArgsConstructor` pochodzi z biblioteki Lombok i automatycznie generuje konstruktor przyjmujący wszystkie pola oznaczone jako `final`
lub z adnotacją `@NonNull`.*

- Wstrzykiwanie przez konstruktor z wykorzystaniem adnotacji `@RequiredArgsConstructor` oraz `@Qualifier`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ja bym usunął z tego wpisu te informacje o @qualifier. W tej postaci można odnieść wrażenie, że @qualifier działa tylko w tym konkretnym przypadku, podczas gdy można go użyć w pozostałych trybach czyli jawny konstruktor, settery i autowired.
Ewentualnie można opisać działanie w osobnym akapicie i tam rozróżnić użycie z Lombok i bez.

```java
@Component
@RequiredArgsConstructor
public class ServiceA {
@Qualifier("serviceB")
private final ServiceB serviceB;
}
```
*Adnotacja `@Qualifier` jest przydatna, gdy w kontekście Springa istnieje wiele beanów tego samego typu i chcemy wskazać,
który z nich ma zostać wstrzyknięty.*

W pliku `lombok.config` należy dodać wpis:

```
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
```

- Wstrzykiwanie przez settery (metody ustawiające)
```java
@Component
public class ServiceA {
private ServiceB serviceB;

@Autowired
public void setServiceB(ServiceB serviceB) {
this.serviceB = serviceB;
}
}
```
*Wstrzykiwanie przez settery może być uzasadnione, gdy zależność jest opcjonalna lub gdy pracujemy z kodem legacy, gdzie nie możemy zmienić konstruktora.*

- Wstrzykiwanie przez pola
```java
@Component
public class ServiceA {
@Autowired
private ServiceB serviceB;
}
```
*Wstrzykiwanie przez pola jest najmniej zalecane, ponieważ utrudnia testowanie i nie pozwala na oznaczenie zależności jako finalne.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jest najmniej zalecanym podejściem, ponieważ

Może być stosowane w wyjątkowych przypadkach, np. w bardzo prostych klasach lub kodzie legacy.*

## Którą metodę powinniśmy wykorzystywać i dlaczego?

Rekomendowanym podejściem jest wykorzystywanie wstrzykiwania przez konstruktor. Oto powody, dla których to podejście jest preferowane:

- **Wymuszenie przekazania zależności podczas tworzenia obiektu** – wstrzykiwanie przez konstruktor gwarantuje,
że wszystkie wymagane zależności zostaną dostarczone w momencie tworzenia instancji obiektu. Dzięki temu unikamy sytuacji,
w której klasa może być używana bez pełnych zależności, co mogłoby prowadzić do błędów w czasie działania.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tutaj zmieniłbym na runtime (jeśli to o to chodziło), albo

Dzięki temu unikamy sytuacji, w której klasa może być używana bez pełnych zależności, zapobiegając tym samym nieprzewidzianym awariom już po uruchomieniu aplikacji.

- **Niezmienność obiektu** – przypisanie zależności poprzez konstruktor oznacza, że pola te mogą być oznaczone jako `final`,
co zapewnia ich niezmienność i chroni przed niepożądanymi modyfikacjami w trakcie cyklu życia obiektu. Taka konstrukcja promuje czystszy i bardziej bezpieczny kod.
- **Testy jednostkowe** – wstrzykiwanie przez konstruktor ułatwia testowanie,
ponieważ możemy ręcznie dostarczać zależności (np. mocki) bez potrzeby używania narzędzi wspomagających, jak refleksja.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

takich narzędzi wspomagających, jak refleksja.

To pozwala na łatwiejsze pisanie testów jednostkowych i zachowanie pełnej kontroli nad zależnościami podczas testowania.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To ułatwia pisanie testów jednostkowych i pozwala na zachowanie pełnej kontroli nad zależnościami podczas testowania.



Wstrzykiwanie przez konstruktor wspiera zasady **SOLID**, w szczególności:

- **Single Responsibility Principle (SRP)** – dzięki tej metodzie klasa ma jasno zdefiniowane odpowiedzialności,
a zarządzanie zależnościami odbywa się na poziomie konstrukcji obiektu.
- **Dependency Inversion Principle (DIP)** – poprzez konstruktor, zależności są wprowadzane od zewnątrz,
co wzmacnia niezależność od szczegółowych implementacji.

Wstrzykiwanie przez konstruktor sprawia, że zależności klasy są jasno widoczne i wyraźnie zadeklarowane w jej definicji.
Programista, przeglądając kod, natychmiast widzi, jakie komponenty są wymagane do działania klasy.

W przypadku wstrzykiwania przez konstruktor łatwiej jest zidentyfikować brakujące zależności lub problemy z ich konfiguracją podczas uruchamiania aplikacji,
ponieważ Spring od razu poinformuje nas o braku zależności, której nie można dostarczyć.

Konstruktor pozwala lepiej unikać problemów z cyklicznymi zależnościami, które mogą występować w innych formach wstrzykiwania (np. wstrzykiwanie przez pola).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Konstruktor pomaga w szybszym wykrywaniu problemów z cyklicznymi zależnościami(...)

Spring będzie w stanie zidentyfikować takie sytuacje już na etapie konfigurowania obiektów, co ułatwia ich eliminację.

## Podsumowanie

Wstrzykiwanie zależności przez konstruktor to najlepsza praktyka w aplikacjach Spring.
Zapewnia bezpieczeństwo, czytelność kodu, łatwość testowania i zgodność z zasadami SOLID.
Warto stosować to podejście zawsze, gdy to możliwe, a inne metody rezerwować dla szczególnych przypadków (opcjonalne zależności, legacy code).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jest ok, ale może akurat:

Warto przyjąć to podejście jako domyślny standard w każdym projekcie, a inne metody (...)

Dzięki temu Twój kod będzie bardziej niezawodny i łatwiejszy w utrzymaniu.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

czekam na źródła @BartoszPietrowiak

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.