Zum Hauptinhalt springen

Woche 1, Tag 3 — Beans und Bean-Definitionen

Ziel

Heute verstehst du, was eine Spring Bean wirklich ist.

Die Kernfragen:

  1. Was ist eine Spring Bean?
  2. Was ist eine BeanDefinition?
  3. Wie registriert Spring Beans?
  4. Was ist der Unterschied zwischen @Component und @Bean?
  5. Was ist der Unterschied zwischen @Component, @Service, @Repository und @Controller?
  6. Wann nutzt du welche Annotation?
  7. Welche typischen Prüfungsfallen gibt es zu Beans?

1. Kurz-Wiederholung von Tag 2

Am Tag 2 hast du gelernt:

  • ApplicationContext ist der zentrale Spring-Container.
  • ApplicationContext verwaltet Spring Beans.
  • BeanFactory ist der Basis-Container.
  • ApplicationContext erweitert BeanFactory.
  • BeanDefinition ist das Rezept.
  • Bean ist das echte Objekt.

Merksatz:


BeanDefinition ist das Rezept. Bean ist das Objekt.

Heute gehst du tiefer in Beans.


2. Was ist eine Spring Bean?

Eine Spring Bean ist ein vom Spring IoC-Container verwaltetes Objekt.

Kurzdefinition:

Eine Spring Bean ist ein Objekt, das Spring erzeugt, konfiguriert, verdrahtet und verwaltet.

Beispiel:


@Service
public class OrderService {
}

Wenn Spring diese Klasse findet und ein Objekt daraus erzeugt, ist das Objekt eine Spring Bean.


3. Normales Java-Objekt vs. Spring Bean

Normales Java-Objekt


OrderService orderService = new OrderService();

Dieses Objekt erzeugst du manuell.

Spring verwaltet es nicht.

Spring kann nicht automatisch:

  • Abhängigkeiten injizieren
  • Lifecycle-Callbacks aufrufen
  • @Transactional anwenden
  • Security-Proxies legen
  • Zerstörung steuern

Spring Bean


@Service
public class OrderService {
}

Spring erzeugt und verwaltet dieses Objekt.

Spring kann:

  • Abhängigkeiten injizieren
  • den Lifecycle steuern
  • AOP-Proxies anwenden
  • Transaktionen anwenden
  • Security anwenden
  • dieselbe Singleton-Instanz wiederverwenden

4. Prüfungsdefinition

Für die Prüfung:

Eine Spring Bean ist ein Objekt, dessen Lebenszyklus vom Spring IoC-Container verwaltet wird. Spring erzeugt das Objekt, injiziert Abhängigkeiten, konfiguriert es und kann zusätzliches Verhalten anwenden: Lifecycle-Callbacks, AOP-Proxies, Transaktionen und Security.


5. Was verwaltet Spring genau?

Wenn Spring eine Bean verwaltet, kann er steuern:


1. Objekterzeugung
2. Dependency Injection
3. Konfiguration
4. Bean-Name
5. Bean-Scope
6. Initialisierung
7. Zerstörung
8. AOP-Proxy-Wrapping
9. Transaktionsverhalten
10. Security-Methoden-Interception

Beispiel:


@Service
public class PaymentService {

@Transactional
public void pay() {
// business logic
}
}

Spring erzeugt nicht nur PaymentService.

Er kann die Bean auch mit einem Proxy wrappen, damit @Transactional greift.


6. Was ist eine BeanDefinition?

Bevor Spring eine Bean erzeugt, speichert er Metadaten darüber.

Diese Metadaten heißen BeanDefinition.

Kurzdefinition:

Eine BeanDefinition ist Metadaten, die Spring sagen, wie eine Bean erzeugt und verwaltet werden soll.

Eine BeanDefinition kann enthalten:

  • Bean-Klasse
  • Bean-Name
  • Scope
  • Konstruktor-Argumente
  • Abhängigkeiten
  • Lazy/Eager-Einstellung
  • Init-Methode
  • Destroy-Methode
  • Factory-Methode
  • ob die Bean @Primary ist
  • Qualifiers

7. BeanDefinition vs. Bean

KonzeptBedeutung
BeanDefinitionMetadaten / Rezept
BeanDas echte Objekt

Beispiel:


BeanDefinition:
- Klasse: OrderService
- Scope: singleton
- Abhängigkeit: OrderRepository

Bean:
- das echte OrderService-Objekt im Speicher

Merksatz:

BeanDefinition ist das Rezept. Bean ist das fertige Gericht.


8. Wie registriert Spring Beans?

Spring kann Beans auf verschiedene Wege registrieren.

Die zwei wichtigsten:

  1. Component Scanning
  2. @Bean-Methoden in Konfigurationsklassen

9. Weg 1 — Component Scanning

Spring scannt Packages und sucht Annotationen wie:


@Component
@Service
@Repository
@Controller
@RestController

Beispiel:


@Service
public class OrderService {
}

Spring sieht @Service, legt eine BeanDefinition an und erzeugt später die Bean.


10. Was ist Component Scanning?

Component Scanning heißt:

Spring durchsucht ausgewählte Packages nach Klassen mit Spring-Stereotyp-Annotationen.

Beispiel:


@SpringBootApplication
public class MyApplication {
}

@SpringBootApplication enthält:


@ComponentScan

Standardmäßig scannt Spring das Package der Hauptklasse und alle Unterpackages.


11. Gute Package-Struktur

Gute Struktur:


com.example.app
├── MyApplication.java
├── controller
│ └── OrderController.java
├── service
│ └── OrderService.java
└── repository
└── OrderRepository.java

Liegt MyApplication in:


com.example.app

scannt Spring:


com.example.app.controller
com.example.app.service
com.example.app.repository

Das funktioniert gut.


12. Schlechte Package-Struktur

Schlechte Struktur:


com.example.app
└── MyApplication.java

com.other.service
└── OrderService.java

Liegt die Hauptklasse in com.example.app, scannt Spring com.other.service nicht automatisch.

OrderService wird dann keine Bean.

Prüfungsfalle:

Eine Klasse mit @Service wird keine Bean, wenn sie außerhalb des Component Scans liegt.


13. Weg 2 — @Bean-Methode

Der zweite gängige Weg: @Bean.

Beispiel:


@Configuration
public class AppConfig {

@Bean
public Clock clock() {
return Clock.systemUTC();
}
}

Der Rückgabewert der Methode wird zur Spring Bean.

Spring registriert eine Bean mit dem Namen:


clock

Der Bean-Typ ist:


Clock

14. Wann @Bean nutzen?

Nutze @Bean, wenn:

  • die Klasse aus einer Drittanbieter-Lib kommt
  • du die Klasse nicht ändern kannst
  • die Erzeugung eigene Logik braucht
  • du ein Objekt manuell konfigurieren willst
  • du Konstruktor-Werte selbst wählen musst

Beispiel:


@Configuration
public class AppConfig {

@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.findAndRegisterModules();
return mapper;
}
}

ObjectMapper kommt von Jackson — nicht aus deiner App.

@Bean passt hier gut.


15. @Component vs. @Bean

Sehr wichtig.

Thema@Component@Bean
Wo?Auf KlasseAuf Methode
Wer erzeugt?Spring erzeugt die KlasseMethode liefert Objekt
Am besten fürEigene KlassenDrittanbieter oder Custom Setup
Component Scan nötig?JaKonfigurationsklasse muss registriert sein
BeispielOrderServiceClock, ObjectMapper, RestTemplate

16. Beispiel: @Component

Nutze @Component oder @Service für eigene App-Klassen.


@Service
public class OrderService {

public void createOrder() {
System.out.println("Order created");
}
}

Einfach und sauber.


17. Beispiel: @Bean

Nutze @Bean, wenn du die Klasse nicht annotieren kannst.


@Configuration
public class TimeConfig {

@Bean
public Clock clock() {
return Clock.systemUTC();
}
}

Du kannst @Component nicht auf Clock setzen — das ist eine Java-Lib-Klasse.

Also erzeugst du sie mit @Bean.


18. Stereotyp-Annotationen

Spring hat mehrere gängige Stereotyp-Annotationen:


@Component
@Service
@Repository
@Controller
@RestController

Alle können Spring Beans registrieren.

Sie signalisieren aber unterschiedliche Rollen.


19. @Component

@Component ist die generische Annotation.

Für allgemeine Spring-verwaltete Klassen.

Beispiel:


@Component
public class SlugGenerator {
}

Bedeutung:

Das ist eine Spring-verwaltete Komponente.


20. @Service

@Service für Service-Layer-Klassen.

Beispiel:


@Service
public class OrderService {
}

Bedeutung:

Diese Klasse enthält Business-Logik.

Der Service-Layer koordiniert typischerweise:

  • Validierung
  • Business-Regeln
  • Repositories
  • Transaktionen
  • Domain-Logik

21. @Repository

@Repository für Persistence-Layer-Klassen.

Beispiel:


@Repository
public class JdbcOrderRepository {
}

Bedeutung:

Diese Klasse spricht mit der Datenbank oder dem Persistence-System.

Wichtig für die Prüfung:

@Repository kann Persistence Exception Translation aktivieren.

Datenbank-spezifische Exceptions werden in Springs DataAccessException-Hierarchie übersetzt.


22. @Controller

@Controller für Spring-MVC-Controller, die meist Views zurückgeben.

Beispiel:


@Controller
public class HomeController {

@GetMapping("/")
public String home() {
return "home";
}
}

Typisch für klassische serverseitig gerenderte MVC-Apps.


23. @RestController

@RestController für REST-APIs.

Beispiel:


@RestController
@RequestMapping("/api/orders")
public class OrderController {

@GetMapping("/{id}")
public OrderResponse getOrder(@PathVariable Long id) {
return new OrderResponse(id, "Book");
}
}

Wichtig:


@RestController

ist eine Kombination aus:


@Controller
@ResponseBody

Rückgabewerte landen direkt im HTTP-Response-Body — meist als JSON.


24. Vergleichstabelle

AnnotationLayerHauptbedeutung
@Componentgenerischallgemeine Spring Bean
@ServiceServiceBusiness-Logik
@RepositoryPersistenceDB-Zugriff + Exception Translation
@ControllerWeb MVCController mit Views
@RestControllerREST APIController mit Response Body / JSON
@ConfigurationConfigKlasse mit Bean-Methoden
@BeanConfig-MethodeRückgabewert wird Bean

25. Sind @Service und @Repository technisch unterschiedlich?

Technisch sind beide Spezialisierungen von @Component.

Beide können Beans registrieren.

Aber sie sind nicht nur Dekoration.

Wichtiger Unterschied:

  • @Service signalisiert Business-Logik-Rolle.
  • @Repository signalisiert Persistence-Rolle und kann Exception Translation unterstützen.

Merksatz:

@Service und @Repository sind beides Component-Stereotypen — @Repository hat aber spezielles Verhalten bei Persistence Exception Translation.


26. Standard-Bean-Name

Standardmäßig leitet Spring den Bean-Namen vom Klassennamen ab — erster Buchstabe klein.

Beispiel:


@Service
public class OrderService {
}

Standard-Bean-Name:


orderService

Weiteres Beispiel:


@Component
public class EmailSender {
}

Standard-Bean-Name:


emailSender

27. Eigener Bean-Name

Du kannst einen eigenen Namen setzen.


@Service("mainOrderService")
public class OrderService {
}

Bean-Name:


mainOrderService

Mit @Bean:


@Bean("utcClock")
public Clock clock() {
return Clock.systemUTC();
}

Bean-Name:


utcClock

28. Kann eine Klasse mehrere Beans haben?

Ja — aber nicht direkt mit einer @Component-Klasse.

Mit @Bean kannst du mehrere Beans desselben Typs erzeugen.

Beispiel:


@Configuration
public class ClockConfig {

@Bean
public Clock utcClock() {
return Clock.systemUTC();
}

@Bean
public Clock systemClock() {
return Clock.systemDefaultZone();
}
}

Jetzt hat Spring zwei Clock-Beans:


utcClock
systemClock

Braucht eine andere Bean Clock, weiß Spring vielleicht nicht, welche er injizieren soll.

Das erzeugt Mehrdeutigkeit.

Später löst du das mit:


@Primary
@Qualifier

29. Was passiert bei zwei Beans desselben Typs?

Beispiel:


@Bean
public Clock utcClock() {
return Clock.systemUTC();
}

@Bean
public Clock berlinClock() {
return Clock.system(ZoneId.of("Europe/Berlin"));
}

Und eine andere Klasse braucht:


public TimeService(Clock clock) {
this.clock = clock;
}

Problem:


Spring findet zwei Clock-Beans.
Spring weiß nicht, welche er injizieren soll.
App startet nicht.

Mögliche Lösungen:

  • eine Bean als @Primary markieren
  • @Qualifier nutzen
  • per spezifischem Bean-Namen injizieren
  • List<Clock> injizieren, wenn du alle Beans willst

30. @Primary

@Primary sagt Spring:

Nimm diese Bean standardmäßig, wenn mehrere Kandidaten existieren.

Beispiel:


@Bean
@Primary
public Clock utcClock() {
return Clock.systemUTC();
}

@Bean
public Clock berlinClock() {
return Clock.system(ZoneId.of("Europe/Berlin"));
}

Jetzt funktioniert das:


public TimeService(Clock clock) {
this.clock = clock;
}

Spring injiziert utcClock.


31. @Qualifier

@Qualifier sagt Spring genau, welche Bean injiziert werden soll.

Beispiel:


public TimeService(@Qualifier("berlinClock") Clock clock) {
this.clock = clock;
}

Spring injiziert:


berlinClock

Auch wenn eine andere Bean @Primary ist — @Qualifier ist spezifischer.

Merksatz:

@Primary ist die Standardwahl. @Qualifier ist die exakte Wahl.


32. Kann ich alle Beans eines Typs injizieren?

Ja.

Beispiel:


@Component
public class NotificationService {

private final List<NotificationSender> senders;

public NotificationService(List<NotificationSender> senders) {
this.senders = senders;
}
}

Wenn du hast:


@Component
public class EmailSender implements NotificationSender {
}

@Component
public class SmsSender implements NotificationSender {
}

injiziert Spring beide in die Liste.

Nützlich für Strategy-Patterns.


33. Kann eine Bean optional sein?

Ja.

Optionen:


Optional<MyService>
ObjectProvider<MyService>
@Nullable

Beispiel:


@Component
public class ReportService {

public ReportService(Optional<AuditService> auditService) {
}
}

Für feinere Kontrolle:


@Component
public class ReportService {

private final ObjectProvider<AuditService> auditServiceProvider;

public ReportService(ObjectProvider<AuditService> auditServiceProvider) {
this.auditServiceProvider = auditServiceProvider;
}
}

Nützlich, wenn die Abhängigkeit vielleicht nicht existiert.


34. Kann ich eine Bean manuell holen?

Ja — im normalen Business-Code aber meist nicht empfohlen.

Beispiel:


ApplicationContext context = SpringApplication.run(App.class, args);

OrderService orderService = context.getBean(OrderService.class);

Funktioniert — normalerweise bevorzugst du aber Constructor Injection.

Warum?

Weil Constructor Injection Abhängigkeiten sichtbar macht.

Schlechter Stil im Service-Code:


@Component
public class OrderService {

private final ApplicationContext context;

public OrderService(ApplicationContext context) {
this.context = context;
}

public void process() {
PaymentService paymentService = context.getBean(PaymentService.class);
}
}

Das versteckt Abhängigkeiten.

Besser:


@Component
public class OrderService {

private final PaymentService paymentService;

public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}

35. Ist jede Bean ein Singleton?

Nein.

Der Standard-Scope ist singleton — Spring unterstützt aber verschiedene Scopes.

Gängige Scopes:


singleton
prototype
request
session
application
websocket

Heute merkst du dir:

Standard-Scope ist singleton.

Scopes schauen wir später genauer an.


36. Bedeutet Singleton das Java-Singleton-Pattern?

Nein.

Spring-Singleton heißt:

eine Bean-Instanz pro Spring-Container.

Java-Singleton-Pattern meist:

eine Instanz pro JVM, gesteuert über statischen Zugriff.

Das ist nicht dasselbe.

Prüfungsfalle:

Spring-Singleton ist nicht dasselbe wie das klassische Java-Singleton-Pattern.


37. Was passiert, wenn die Bean-Erzeugung fehlschlägt?

Kann Spring eine erforderliche Bean nicht erzeugen, startet die App meist nicht.

Beispiel:


@Service
public class OrderService {

public OrderService(OrderRepository orderRepository) {
}
}

Aber keine OrderRepository-Bean existiert.

Dann wirft Spring z. B.:


No qualifying bean of type 'OrderRepository' available

Nützlich — Fehler werden früh erkannt.


38. @Service gesetzt, Spring findet die Klasse trotzdem nicht?

Mögliche Gründe:

  1. Klasse liegt außerhalb des gescannten Packages.
  2. Klasse ist nicht public oder nicht instanziierbar.
  3. Konstruktor-Abhängigkeiten fehlen.
  4. Annotation aus falschem Package importiert.
  5. Profil-Bedingung passt nicht.
  6. Bean ist conditional und die Bedingung ist false.

Am häufigsten für Einsteiger:

Klasse liegt außerhalb des Component Scans.


39. Können Interfaces Beans sein?

Ein Interface allein ist meist keine Bean — Spring kann kein Interface instanziieren.

Beispiel:


public interface OrderRepository {
}

Das reicht nicht.

Spring braucht eine Implementierung:


@Repository
public class JpaOrderRepository implements OrderRepository {
}

Spring Data JPA ist speziell:


public interface OrderRepository extends JpaRepository<Order, Long> {
}

Spring Data erzeugt automatisch eine Proxy-Implementierung.

Das Repository-Interface kann also über Spring-Data-Infrastruktur zur Bean werden.


40. Können abstrakte Klassen Beans sein?

Meist nein — Spring kann keine abstrakte Klasse direkt instanziieren.

Beispiel:


@Component
public abstract class BaseService {
}

Das kann nicht als normale Bean erzeugt werden — die Klasse ist abstrakt.

Konkrete Subklassen können aber Beans sein.


41. Was ist ein Bean-Kandidat?

Ein Bean-Kandidat ist eine Bean, die Spring nutzen kann, um eine Abhängigkeit zu erfüllen.

Beispiel:


public OrderService(PaymentService paymentService) {
}

Spring sucht Beans vom Typ:


PaymentService

Alle passenden Beans sind Kandidaten.

Gibt es genau einen, injiziert Spring ihn.

Gibt es mehrere, braucht Spring mehr Information.


42. Was ist Autowiring?

Autowiring heißt: Spring löst Abhängigkeiten automatisch auf und injiziert sie.

Beispiel:


@Service
public class OrderService {

private final OrderRepository orderRepository;

public OrderService(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
}

Spring sieht den Konstruktor-Parameter und injiziert automatisch eine OrderRepository-Bean.

In modernem Spring ist @Autowired bei nur einem Konstruktor optional.


43. Constructor Injection mit @Autowired

Alter oder expliziter Stil:


@Service
public class OrderService {

private final OrderRepository orderRepository;

@Autowired
public OrderService(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
}

Moderner Stil:


@Service
public class OrderService {

private final OrderRepository orderRepository;

public OrderService(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
}

Beides funktioniert bei nur einem Konstruktor.

Prüfungsfalle:

@Autowired auf einem einzigen Konstruktor ist in modernem Spring optional.


44. Field Injection

Field Injection:


@Service
public class OrderService {

@Autowired
private OrderRepository orderRepository;
}

Funktioniert — ist aber nicht empfohlen.

Warum?

  • Abhängigkeiten sind versteckt
  • schwerer testbar
  • Felder können nicht final sein
  • Objekt kann in ungültigem Zustand entstehen
  • fördert schlechtes Design

Best Practice:

Constructor Injection bevorzugen.


45. Setter Injection

Setter Injection:


@Service
public class OrderService {

private OrderRepository orderRepository;

@Autowired
public void setOrderRepository(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
}

Setter Injection meist für optionale Abhängigkeiten.

Für erforderliche Abhängigkeiten: Constructor Injection.


46. Constructor vs. Setter vs. Field Injection

TypAm besten fürEmpfehlung
Constructor Injectionerforderliche Depsam besten
Setter Injectionoptionale Depsakzeptabel
Field Injectionschnelle Demos/Testsin Produktion meiden

Merksatz:

Erforderliche Abhängigkeiten per Constructor injizieren.


47. Kleines Code-Beispiel

Erstelle dieses Mini-Beispiel:


public interface NotificationSender {
void send(String message);
}

@Component
public class EmailNotificationSender implements NotificationSender {

@Override
public void send(String message) {
System.out.println("Email: " + message);
}
}

@Service
public class OrderService {

private final NotificationSender notificationSender;

public OrderService(NotificationSender notificationSender) {
this.notificationSender = notificationSender;
}

public void createOrder() {
notificationSender.send("Order created");
}
}

Frage:

Warum kann Spring EmailNotificationSender in NotificationSender injizieren?

Antwort:

Weil EmailNotificationSender eine Spring Bean ist und NotificationSender implementiert. Spring kann per Interface-Typ injizieren, wenn es genau eine passende Implementierung gibt.


48. Code-Beispiel mit Mehrdeutigkeit

Jetzt hinzufügen:


@Component
public class SmsNotificationSender implements NotificationSender {

@Override
public void send(String message) {
System.out.println("SMS: " + message);
}
}

Jetzt hat Spring zwei Beans vom Typ NotificationSender:


emailNotificationSender
smsNotificationSender

Dieser Konstruktor ist mehrdeutig:


public OrderService(NotificationSender notificationSender) {
}

Spring weiß nicht, welche Bean er injizieren soll.

Fix:


public OrderService(
@Qualifier("emailNotificationSender") NotificationSender notificationSender
) {
this.notificationSender = notificationSender;
}

49. Prüfungsfallen

Falle 1

@Service, @Repository und @Controller sind Spezialisierungen von @Component.


Falle 2

@Repository kann Exception Translation bieten.


Falle 3

@RestController = @Controller + @ResponseBody.


Falle 4

Eine Klasse mit @Service ist keine Bean, wenn sie außerhalb des Component Scans liegt.


Falle 5

Ein mit new erzeugtes Objekt wird nicht automatisch von Spring verwaltet.


Falle 6

BeanDefinition = Metadaten. Bean = das echte Objekt.


Falle 7

@Bean ist nützlich für Drittanbieter-Klassen oder eigene Erzeugungslogik.


Falle 8

Mehrere Beans desselben Typs → Spring braucht @Primary, @Qualifier oder eine andere Auflösung.


Falle 9

@Autowired auf einem einzigen Konstruktor ist in modernem Spring optional.


Falle 10

Spring-Singleton = eine Instanz pro Container — nicht das klassische Java-Singleton-Pattern.


50. Interview-Antwort

Frage:

Was ist eine Spring Bean?

Gute Antwort:

Eine Spring Bean ist ein vom Spring IoC-Container verwaltetes Objekt. Spring erzeugt die Bean, injiziert Abhängigkeiten, konfiguriert sie und steuert den Lebenszyklus. Beans werden per Component Scanning mit Annotationen wie @Component, @Service und @Repository registriert — oder manuell über @Bean-Methoden in Konfigurationsklassen. Weil Spring das Objekt verwaltet, kann er auch AOP-Proxies, Transaktionen und Security anwenden. Ein normales Objekt mit new ist nicht automatisch eine Spring Bean.


51. Interview-Antwort

Frage:

Was ist der Unterschied zwischen @Component und @Bean?

Gute Antwort:

@Component steht auf einer Klasse und wird per Component Scanning gefunden — meist für eigene App-Klassen wie Services oder Helfer. @Bean steht auf einer Methode in einer Konfigurationsklasse; der Rückgabewert wird zur Spring Bean. @Bean ist nützlich für Drittanbieter-Objekte, manuelle Konfiguration oder wenn du die Klasse nicht direkt annotieren kannst.


52. Interview-Antwort

Frage:

Was ist der Unterschied zwischen @Service und @Repository?

Gute Antwort:

Beide sind Stereotyp-Annotationen und Spezialisierungen von @Component — beide registrieren Spring Beans. Der Unterschied ist semantisch und technisch. @Service markiert Business-Logik im Service-Layer. @Repository markiert Persistence-Layer und kann Persistence Exception Translation in Springs DataAccessException-Hierarchie unterstützen.


53. Interview-Antwort

Frage:

Warum wird Constructor Injection empfohlen?

Gute Antwort:

Constructor Injection macht erforderliche Abhängigkeiten explizit. Felder können final sein, Immutability wird unterstützt, Tests werden einfacher. Das Objekt kann nicht ohne seine Pflicht-Abhängigkeiten entstehen. Field Injection versteckt Abhängigkeiten und erschwert Tests — deshalb bevorzugt man Constructor Injection in Produktionscode.


Übungsfragen

Frage 1

Was ist eine Spring Bean?

Antwort:

Ein vom Spring IoC-Container erzeugtes und verwaltetes Objekt. Spring kann es erzeugen, Abhängigkeiten injizieren, konfigurieren, den Lebenszyklus steuern und zusätzliches Verhalten anwenden: AOP-Proxies, Transaktionen, Security.


Frage 2

Was ist eine BeanDefinition?

Antwort:

Metadaten, die Spring sagen, wie eine Bean erzeugt und verwaltet werden soll: Bean-Klasse, Name, Scope, Abhängigkeiten, Konstruktor-Argumente, Init/Destroy-Methode, Lazy/Eager-Verhalten.


Frage 3

Unterschied BeanDefinition und Bean?

Antwort:

BeanDefinition ist das Rezept bzw. die Metadaten. Eine Bean ist das echte Objekt, das daraus entsteht und von Spring verwaltet wird.


Frage 4

Unterschied @Component und @Bean?

Antwort:

@Component steht auf einer Klasse und wird per Component Scanning gefunden. @Bean steht auf einer Methode in einer Konfigurationsklasse — der Rückgabewert wird zur Spring Bean.


Frage 5

Wann @Bean statt @Component?

Antwort:

Wenn die Klasse aus einer Drittanbieter-Lib kommt, du sie nicht ändern kannst oder die Erzeugung eigene Konfigurationslogik braucht.


Frage 6

Unterschied @Component, @Service und @Repository?

Antwort:

@Component ist generisch. @Service für Business-Logik im Service-Layer. @Repository für Persistence-Layer mit Datenzugriff.


Frage 7

Was ist besonders an @Repository?

Antwort:

@Repository kann Persistence Exception Translation unterstützen — DB-spezifische Exceptions werden in Springs DataAccessException-Hierarchie übersetzt.


Frage 8

Was enthält @RestController?

Antwort:

@Controller und @ResponseBody. Für REST-APIs, bei denen Rückgabewerte direkt in den HTTP-Response-Body geschrieben werden — meist als JSON.


Frage 9

Ist das eine Spring Bean?


OrderService service = new OrderService();

Antwort:

Nein. Mit new erzeugt — Spring verwaltet es nicht automatisch.


Frage 10

Wird diese Klasse automatisch eine Bean?


@Service
public class OrderService {
}

Antwort:

Sie kann eine Spring Bean werden, wenn sie in einem von Spring gescannten Package liegt.


Frage 11

Was kann verhindern, dass diese @Service-Klasse eine Bean wird?


@Service
public class OrderService {
}

Antwort:

Mögliche Gründe: außerhalb des gescannten Packages, fehlende Abhängigkeit, aktives Profil passt nicht, Bedingung ist false, Klasse nicht instanziierbar.


Frage 12

Was passiert bei zwei Beans desselben Typs ohne eindeutige Wahl?

Antwort:

Spring startet nicht — Mehrdeutigkeitsfehler. Auflösung mit @Primary, @Qualifier, spezifischerem Typ oder Collection-Injection.


Frage 13

Unterschied @Primary und @Qualifier?

Antwort:

@Primary markiert die Standard-Bean bei mehreren Kandidaten. @Qualifier wählt explizit eine bestimmte Bean — präziser.


Frage 14

Warum ist Constructor Injection besser als Field Injection?

Antwort:

Abhängigkeiten sind explizit, Felder können final sein, Immutability und Testbarkeit verbessern sich — das Objekt entsteht nicht ohne Pflicht-Abhängigkeiten.


Frage 15

Ist @Autowired auf einem einzigen Konstruktor nötig?

Antwort:

Nein. In modernem Spring ist es bei nur einem Konstruktor optional.


Frage 16

Kann ein Interface eine Spring Bean sein?

Antwort:

Ein Interface allein meist nicht — Spring kann es nicht instanziieren. Frameworks wie Spring Data JPA erzeugen aber Proxy-Implementierungen für Repository-Interfaces.


Frage 17

Kann Spring per Interface-Typ injizieren?

Antwort:

Ja — wenn es genau eine passende Implementierung gibt oder Mehrdeutigkeit mit @Primary oder @Qualifier aufgelöst ist.


Frage 18

Standard-Bean-Name für diese Klasse?


@Service
public class PaymentService {
}

Antwort:


paymentService

Spring nutzt den Klassennamen mit kleinem Anfangsbuchstaben.


Frage 19

Standard-Bean-Scope?

Antwort:


singleton

Frage 20

Ist Spring-Singleton dasselbe wie das Java-Singleton-Pattern?

Antwort:

Nein. Spring-Singleton = eine Instanz pro Spring-Container. Java-Singleton-Pattern = eine Instanz pro JVM über statischen Zugriff.

Merksätze zum Mitnehmen

  • Spring Bean = vom Container verwaltetes Objekt.
  • BeanDefinition ist das Rezept. Bean ist das Objekt.
  • @Component steht auf Klassen.
  • @Bean steht auf Methoden.
  • @Bean für Drittanbieter oder eigene Erzeugungslogik.
  • @Service = Business-Logik.
  • @Repository = Persistence + Exception Translation.
  • @RestController = @Controller + @ResponseBody.
  • Klasse muss im Component Scan liegen, um Bean zu werden.
  • Mit new erzeugte Objekte sind nicht automatisch Spring-verwaltet.
  • Constructor Injection bevorzugen.
  • @Autowired auf einem Konstruktor ist optional.
  • @Primary = Standard-Bean.
  • @Qualifier = exakte Bean.
  • Standard-Scope ist singleton.
  • Spring-Singleton ≠ Java-Singleton-Pattern.