Woche 2 — Review: Konfiguration, Profile, Scopes und Bean Lifecycle
Ziel
Dieses Review prüft, ob du Woche 2 wirklich verstanden hast.
Themen aus Woche 2:
- Java-Konfiguration
@Configuration@Bean- Full vs. lite configuration mode
proxyBeanMethods- Externe Konfiguration
application.propertiesapplication.yml@Value@ConfigurationProperties- Profile
@Profile- Bean scopes
- Singleton vs. prototype
- Request- und session scope
- Scoped proxy
- Bean lifecycle
@PostConstruct@PreDestroyBeanPostProcessor
1. Das große Bild aus Woche 2
Woche 1 hat beantwortet:
Wie erzeugt Spring Objekte und verbindet sie?
Woche 2 beantwortet:
Wie konfiguriert, aktiviert, scoped, initialisiert und zerstört Spring diese Objekte?
Spring erzeugt nicht nur Beans.
Spring steuert auch:
wie Beans konfiguriert werden
welche Beans aktiv sind
wie lange Beans leben
wann Beans initialisiert werden
wann Beans zerstört werden
ob Beans per Proxy laufen
2. Zentrale Merksätze
Auswendig lernen:
@Configuration markiert eine Klasse als Quelle von Bean-Definitionen.
@Bean markiert eine Methode, deren Rückgabewert zu einer Spring Bean wird.
@Component steht auf Klassen.
@Bean steht auf Methoden.
@Bean nutzt du für Drittanbieter-Klassen oder eigene Erzeugungslogik.
Vollständige @Configuration-Klassen werden per Proxy behandelt, um Singleton-Verhalten zu erhalten.
@Configuration(proxyBeanMethods = false) deaktiviert das Proxying von @Bean-Methoden.
Bevorzuge @Bean-Methodenparameter gegenüber direkten Aufrufen anderer @Bean-Methoden.
Externe Konfiguration hält umgebungsspezifische Werte außerhalb des Java-Codes.
application.properties ist flache Key-Value-Konfiguration.
application.yml ist hierarchische Konfiguration.
@Value injiziert einen einzelnen Konfigurationswert.
@ConfigurationProperties bindet gruppierte Konfiguration an ein Java-Objekt.
@ConfigurationProperties-Klassen müssen als Beans registriert werden.
Profile steuern, welche Konfiguration und welche Beans aktiv sind.
application-dev.yml lädt nur, wenn das dev-Profil aktiv ist.
@Profile("dev") heißt: Die Bean ist nur im dev-Profil aktiv.
@Profile("!prod") heißt: Die Bean ist aktiv, wenn prod nicht aktiv ist.
Der Standard-Bean-Scope ist singleton.
Spring-Singleton heißt: eine Bean-Instanz pro Spring-Container.
Prototype scope erzeugt bei jeder Anfrage eine neue Bean.
Ein Prototype, der in einen Singleton injiziert wird, entsteht einmal bei der Erzeugung des Singletons.
ObjectProvider kann einem Singleton helfen, frische Prototype-Instanzen zu holen.
Request scope heißt: eine Bean pro HTTP-Request.
Session scope heißt: eine Bean pro HTTP-Session.
Scoped proxy erlaubt einem Singleton, von einer request- oder session-scoped Bean abzuhängen.
@PostConstruct läuft nach der Dependency Injection.
@PreDestroy läuft vor der Bean-Zerstörung.
BeanPostProcessor kann Beans modifizieren oder wrappen.
AOP-Proxies entstehen oft durch BeanPostProcessors.
3. Concept Map
Spring Configuration
│
├── Java Configuration
│ ├── @Configuration
│ ├── @Bean
│ ├── full configuration mode
│ ├── lite configuration mode
│ └── proxyBeanMethods
│
├── External Configuration
│ ├── application.properties
│ ├── application.yml
│ ├── @Value
│ ├── @ConfigurationProperties
│ ├── environment variables
│ └── command-line arguments
│
├── Profiles
│ ├── dev
│ ├── test
│ ├── prod
│ ├── @Profile
│ ├── application-dev.yml
│ └── @ActiveProfiles
│
├── Bean Scopes
│ ├── singleton
│ ├── prototype
│ ├── request
│ ├── session
│ └── scoped proxy
│
└── Bean Lifecycle
├── instantiate
├── inject dependencies
├── aware callbacks
├── BeanPostProcessor before init
├── @PostConstruct
├── BeanPostProcessor after init
├── bean ready
└── @PreDestroy
4. Wichtigste Prüfungsfallen
Falle 1 — @Bean-Methodenname
@Bean
public Clock clock() {
return Clock.systemUTC();
}
Standard-Bean-Name:
clock
Der Methodenname wird zum Bean-Namen.
Falle 2 — @Component vs. @Bean
Falsch:
@Component und @Bean sind dasselbe.
Richtig:
@Component steht auf einer Klasse.
@Bean steht auf einer Methode.
Falle 3 — Vollständige @Configuration
@Configuration
public class AppConfig {
@Bean
public A a() {
return new A();
}
@Bean
public B b() {
return new B(a());
}
}
Im full configuration mode proxied Spring die Konfigurationsklasse.
Der Aufruf von a() innerhalb von b() liefert die verwaltete Singleton-Bean.
Falle 4 — proxyBeanMethods = false
@Configuration(proxyBeanMethods = false)
public class AppConfig {
@Bean
public A a() {
return new A();
}
@Bean
public B b() {
return new B(a());
}
}
Hier ist a() innerhalb von b() ein normaler Java-Methodenaufruf.
Er kann ein separates A-Objekt erzeugen.
Besser:
@Bean
public B b(A a) {
return new B(a);
}
Falle 5 — Registrierung von @ConfigurationProperties
Das allein reicht nicht:
@ConfigurationProperties(prefix = "jwt")
public record JwtProperties(String secret) {
}
Die Klasse muss auch bei Spring registriert werden.
Nutze eines davon:
@ConfigurationPropertiesScan
oder:
@EnableConfigurationProperties(JwtProperties.class)
oder:
@Component
@ConfigurationProperties(prefix = "jwt")
Falle 6 — @Value funktioniert nur in Spring Beans
Das funktioniert:
@Component
public class AppInfo {
public AppInfo(@Value("${app.name}") String appName) {
}
}
Das funktioniert nicht automatisch:
AppInfo appInfo = new AppInfo();
weil das Objekt nicht von Spring verwaltet wird.
Falle 7 — Profil-Dateien laden nicht automatisch
Diese Datei:
application-prod.yml
lädt nur, wenn:
das prod-Profil aktiv ist
Sie lädt nicht nur, weil die Datei existiert.
Falle 8 — @Profile("default") vs. @Profile("!prod")
@Profile("default")
bedeutet:
aktiv nur, wenn kein explizites Profil aktiv ist
@Profile("!prod")
bedeutet:
aktiv, sobald prod nicht aktiv ist
Falle 9 — Prototype im Singleton
@Service
public class JobService {
private final JobContext jobContext;
public JobService(JobContext jobContext) {
this.jobContext = jobContext;
}
}
Ist JobContext prototype und JobService singleton, injiziert Spring eine Prototype-Instanz, wenn der Singleton erzeugt wird.
Es entsteht kein neuer Prototype bei jedem Methodenaufruf.
Falle 10 — Singleton ist nicht automatisch thread-safe
Spring-Singleton bedeutet:
eine Bean pro Spring-Container
Es bedeutet nicht:
thread-safe
Speichere keinen request-spezifischen, veränderlichen State in Singleton-Feldern.
Falle 11 — Zerstörung von Prototype-Beans
Spring erzeugt und initialisiert Prototype-Beans.
Spring ruft aber beim Schließen des Contexts keine Destroy-Callbacks für Prototype-Beans automatisch auf.
Falle 12 — @PostConstruct
@PostConstruct läuft:
nach der Dependency Injection
nicht davor.
Falle 13 — @PreDestroy
@PreDestroy läuft:
vor der Bean-Zerstörung
meist beim Schließen des Application Context für Singleton-Beans.
Falle 14 — BeanPostProcessor
Ein BeanPostProcessor kann einen Proxy statt der ursprünglichen Bean zurückgeben.
Wichtig für:
AOP
@Transactional
Security
Caching
Falle 15 — Self-Invocation in @PostConstruct
Schlecht:
@PostConstruct
public void init() {
transactionalMethod();
}
@Transactional
public void transactionalMethod() {
}
Das ist Self-Invocation.
Der Aufruf kann den Spring-Proxy umgehen.
@Transactional wirkt möglicherweise nicht wie erwartet.
Übungsfragen
Frage 1
Was macht @Configuration?
Antwort:
@Configuration markiert eine Klasse als Quelle von Spring Bean-Definitionen. Spring verarbeitet die Klasse und registriert Beans aus ihren @Bean-Methoden.
Frage 2
Was macht @Bean?
Antwort:
@Bean markiert eine Methode, deren Rückgabewert als Spring Bean registriert werden soll.
Frage 3
Was ist der Standard-Bean-Name einer @Bean-Methode?
Antwort:
Standardmäßig wird der Methodenname zum Bean-Namen.
Frage 4
Wann solltest du @Bean statt @Component nutzen?
Antwort:
Nutze @Bean für Drittanbieter-Klassen, Klassen, die du nicht ändern kannst, eigene Objekterzeugungslogik, Objekte mit Property-Werten, Factory-Methoden oder mehrere Beans desselben Typs.
Frage 5
Warum werden vollständige @Configuration-Klassen per Proxy behandelt?
Antwort:
Vollständige @Configuration-Klassen werden per Proxy behandelt, damit Spring Aufrufe von @Bean-Methoden abfangen und verwaltete Singleton-Beans zurückgeben kann — statt neue Objekte zu erzeugen.
Frage 6
Was bedeutet @Configuration(proxyBeanMethods = false)?
Antwort:
@Configuration(proxyBeanMethods = false) deaktiviert das Proxying von @Bean-Methoden. Direkte Aufrufe zwischen @Bean-Methoden sind normale Java-Methodenaufrufe.
Frage 7
Was ist externe Konfiguration?
Antwort:
Externe Konfiguration heißt: umgebungsspezifische Werte außerhalb des Java-Codes speichern — z. B. in application.yml, Umgebungsvariablen, Command-Line-Argumenten oder profilspezifischen Dateien.
Frage 8
Was ist der Unterschied zwischen @Value und @ConfigurationProperties?
Antwort:
@Value injiziert einen einzelnen Konfigurationswert. @ConfigurationProperties bindet eine Gruppe zusammengehöriger Konfigurations-Properties an ein Java-Objekt.
Frage 9
Wie registrierst du eine @ConfigurationProperties-Klasse?
Antwort:
Nutze @ConfigurationPropertiesScan, @EnableConfigurationProperties oder füge @Component zusammen mit @ConfigurationProperties hinzu.
Frage 10
Was ist relaxed binding?
Antwort:
Relaxed binding heißt: Spring Boot kann verschiedene Property-Namensstile wie base-url, baseUrl, base_url und BASE_URL an dieselbe Java-Property binden.
Frage 11
Was ist ein Spring-Profil?
Antwort:
Ein Spring-Profil ist ein benannter Umgebungsmodus, der steuert, welche Konfiguration und welche Beans aktiv sind.
Frage 12
Wann lädt application-dev.yml?
Antwort:
application-dev.yml lädt, wenn das dev-Profil aktiv ist.
Frage 13
Was bedeutet @Profile("!prod")?
Antwort:
@Profile("!prod") heißt: Die Bean ist aktiv, wenn das prod-Profil nicht aktiv ist.
Frage 14
Was ist der Standard-Bean-Scope?
Antwort:
Der Standard-Bean-Scope ist singleton.
Frage 15
Was bedeutet singleton in Spring?
Antwort:
Singleton heißt: eine Bean-Instanz pro Spring IoC-Container.
Frage 16
Was bedeutet prototype scope?
Antwort:
Prototype scope heißt: Spring erzeugt bei jeder Anfrage aus dem Container eine neue Bean-Instanz.
Frage 17
Was passiert, wenn eine Prototype-Bean in eine Singleton-Bean injiziert wird?
Antwort:
Die Prototype-Bean entsteht einmal, wenn die Singleton-Bean erzeugt wird. Der Singleton behält dieselbe Prototype-Instanz.
Frage 18
Was ist request scope?
Antwort:
Request scope heißt: eine Bean-Instanz pro HTTP-Request.
Frage 19
Was ist ein scoped proxy?
Antwort:
Ein scoped proxy ist ein Proxy-Objekt, mit dem eine langlebige Bean — z. B. ein Singleton — von einer kurzlebigen scoped Bean abhängen kann, z. B. request-scoped oder session-scoped.
Frage 20
Wann läuft @PostConstruct?
Antwort:
@PostConstruct läuft, nachdem die Bean erzeugt wurde und Abhängigkeiten injiziert sind.
Frage 21
Wann läuft @PreDestroy?
Antwort:
@PreDestroy läuft vor der Bean-Zerstörung — meist beim Schließen des Application Context für Singleton-Beans.
Frage 22
Was ist BeanPostProcessor?
Antwort:
BeanPostProcessor ist ein Spring-Extension Point, der Beans vor und nach der Initialisierung inspizieren, modifizieren oder wrappen kann.
Frage 23
Wie hängen AOP-Proxies mit BeanPostProcessor zusammen?
Antwort:
AOP-Proxies entstehen oft durch BeanPostProcessors. Ein Post-Processor kann eine Bean mit einem Proxy wrappen, der Verhalten wie Transaktionen, Security, Caching oder Logging hinzufügt.
Frage 24
Zerstört Spring Prototype-Beans automatisch?
Antwort:
Nein. Spring erzeugt und initialisiert Prototype-Beans, verwaltet aber deren Zerstörung nicht automatisch.
Frage 25
Warum sollten Singleton-Services meist stateless sein?
Antwort:
Singleton-Services werden über Requests und Threads hinweg geteilt. Speicherst du request-spezifischen, veränderlichen State in Feldern, können verschiedene Requests sich gegenseitig überschreiben — Race Conditions und falsche Daten.
7. Mini-Mock-Prüfung — Woche 2
Anleitung
Ohne Notizen antworten.
Empfohlene Zeit:
35 Minuten
Bestehensgrenze:
80 %
35 Fragen.
Frage 1
Was markiert @Configuration?
A. Einen REST-Endpoint
B. Eine Klasse mit Spring Bean-Definitionen
C. Eine Datenbank-Entity
D. Nur eine Testklasse
Meine Antwort:
Frage 2
Was macht @Bean?
A. Markiert eine Klasse als Datenbanktabelle
B. Markiert eine Methode, deren Rückgabewert zu einer Spring Bean wird
C. Aktiviert CORS
D. Startet Embedded Tomcat
Meine Antwort:
Frage 3
Was ist hier der Standard-Bean-Name?
@Bean
public Clock clock() {
return Clock.systemUTC();
}
A. Clock
B. clock
C. systemUTC
D. timeClock
Meine Antwort:
Frage 4
Wann ist @Bean meist eine gute Wahl?
A. Für Drittanbieter-Klassen oder eigene Objekterzeugung
B. Nur für Entities
C. Nur für Controller
D. Nie
Meine Antwort:
Frage 5
Welche Aussage ist richtig?
A. @Component steht auf Methoden, @Bean auf Klassen
B. @Component steht auf Klassen, @Bean auf Methoden
C. Beide stehen nur auf Feldern
D. Beide sind nur für Tests
Meine Antwort:
Frage 6
Warum proxied Spring vollständige @Configuration-Klassen?
A. Damit Controller schneller werden
B. Um @Bean-Methodenaufrufe abzufangen und Singleton-Verhalten zu erhalten
C. Um JSON zu konvertieren
D. Um SQL-Logging zu aktivieren
Meine Antwort:
Frage 7
Was macht @Configuration(proxyBeanMethods = false)?
A. Deaktiviert alle Beans
B. Deaktiviert das Proxying von @Bean-Methoden
C. Aktiviert request scope
D. Aktiviert Profile
Meine Antwort:
Frage 8
Welcher Stil ist meist besser?
A.
@Bean
public B b() {
return new B(a());
}
B.
@Bean
public B b(A a) {
return new B(a);
}
Meine Antwort:
Frage 9
Was ist externe Konfiguration?
A. Werte in Java-Klassen hardcoden
B. Umgebungsspezifische Werte außerhalb des Java-Codes speichern
C. Entities manuell erzeugen
D. SQL in Controllern schreiben
Meine Antwort:
Frage 10
Welche Datei ist hierarchisch und einrückungssensitiv?
A. application.yml
B. application.properties
C. pom.xml
D. README.md
Meine Antwort:
Frage 11
Wofür ist @Value am besten geeignet?
A. Einen einfachen Konfigurationswert injizieren
B. Eine große Gruppe von Properties binden
C. REST-Endpoints erzeugen
D. Datenbanktabellen erzeugen
Meine Antwort:
Frage 12
Was passiert, wenn diese Property fehlt und kein Default gesetzt ist?
@Value("${app.name}")
private String appName;
A. Spring injiziert stillschweigend null
B. Spring startet meist nicht
C. Spring ignoriert das Feld
D. Spring erzeugt einen Zufallswert
Meine Antwort:
Frage 13
Wofür ist @ConfigurationProperties am besten geeignet?
A. Nur ein einfacher Wert
B. Gruppierte, strukturierte, type-safe Konfiguration
C. Controller-Mapping
D. Nur Bean-Zerstörung
Meine Antwort:
Frage 14
Erzeugt @ConfigurationProperties in jedem Fall automatisch selbst eine Bean?
A. Ja
B. Nein, die Properties-Klasse muss auch registriert werden
C. Nur in XML-Apps
D. Nur in Tests
Meine Antwort:
Frage 15
Was kann @ConfigurationProperties-Klassen registrieren?
A. @ConfigurationPropertiesScan
B. @PathVariable
C. @RequestBody
D. @ControllerAdvice
Meine Antwort:
Frage 16
Was ist relaxed binding?
A. Spring ignoriert fehlende Beans
B. Verschiedene Property-Namensstile können an dieselbe Java-Property binden
C. Spring deaktiviert Validierung
D. Spring entfernt Profile
Meine Antwort:
Frage 17
Woran kann EXTERNAL_API_BASE_URL binden?
A. external-api.base-url
B. Nur external.api.base.url.only
C. Nur die Klasse ExternalApiBaseUrl
D. An nichts
Meine Antwort:
Frage 18
Was ist ein Spring-Profil?
A. Ein Git-Profil
B. Ein benannter Umgebungsmodus, der aktive Config und Beans steuert
C. Eine Datenbanktabelle
D. Ein Java-Package
Meine Antwort:
Frage 19
Wann lädt application-prod.yml?
A. Immer
B. Nur, wenn das prod-Profil aktiv ist
C. Nur, wenn die App fehlschlägt
D. Nur in Tests
Meine Antwort:
Frage 20
Wie aktivierst du das prod-Profil per Command Line?
A. --spring.profiles.active=prod
B. --spring.bean.scope=prod
C. --java.profile=prod
D. --profile.database=prod
Meine Antwort:
Frage 21
Was bedeutet @Profile("dev")?
A. Bean ist nur aktiv, wenn das dev-Profil aktiv ist
B. Bean ist nur in Production aktiv
C. Bean ist nie aktiv
D. Bean ist ein Controller
Meine Antwort:
Frage 22
Was bedeutet @Profile("!prod")?
A. Aktiv nur, wenn prod aktiv ist
B. Aktiv, wenn prod nicht aktiv ist
C. Aktiv nur, wenn kein Profil existiert
D. Ungültiger Ausdruck
Meine Antwort:
Frage 23
Was ist das default profile?
A. Ein Profil, das aktiv ist, wenn kein anderes Profil explizit aktiv ist
B. Immer dev
C. Immer prod
D. Eine Security-Rolle
Meine Antwort:
Frage 24
Was ist der Standard-Spring-Bean-Scope?
A. prototype
B. singleton
C. request
D. session
Meine Antwort:
Frage 25
Was bedeutet Spring-Singleton?
A. Eine Instanz pro JVM, immer
B. Eine Bean-Instanz pro Spring-Container
C. Eine Instanz pro HTTP-Request
D. Eine Instanz pro Datenbankzeile
Meine Antwort:
Frage 26
Sind Spring-Singleton-Beans automatisch thread-safe?
A. Ja
B. Nein
C. Nur Repositories
D. Nur Controller
Meine Antwort:
Frage 27
Was bedeutet prototype scope?
A. Eine Bean pro Anwendung
B. Neue Bean-Instanz bei jeder Anfrage aus dem Container
C. Eine Bean pro HTTP-Session
D. Eine Bean pro Profil
Meine Antwort:
Frage 28
Was passiert, wenn eine Prototype-Bean in einen Singleton injiziert wird?
A. Bei jedem Methodenaufruf des Singletons entsteht ein neuer Prototype
B. Ein Prototype wird injiziert, wenn der Singleton erzeugt wird
C. Spring lehnt alle Prototype-Beans ab
D. Prototype wird request-scoped
Meine Antwort:
Frage 29
Was kann einem Singleton helfen, eine frische Prototype-Instanz zu holen?
A. ObjectProvider<T>
B. @PathVariable
C. @RestController
D. @Entity
Meine Antwort:
Frage 30
Was bedeutet request scope?
A. Eine Bean pro HTTP-Request
B. Eine Bean pro JVM
C. Eine Bean pro Datenbankquery
D. Eine Bean pro Anwendungsprofil
Meine Antwort:
Frage 31
Was bedeutet session scope?
A. Eine Bean pro HTTP-Session
B. Eine Bean pro Methodenaufruf
C. Eine Bean pro Controller
D. Eine Bean pro Maven-Modul
Meine Antwort:
Frage 32
Warum ist ein scoped proxy nützlich?
A. Er erlaubt einem Singleton, von einer request-/session-scoped Bean abzuhängen
B. Er erzeugt Datenbankindizes
C. Er deaktiviert Dependency Injection
D. Er konvertiert Properties zu YAML
Meine Antwort:
Frage 33
Wann läuft @PostConstruct?
A. Vor der Objekterzeugung
B. Nach der Dependency Injection
C. Nur nach dem Shutdown der Anwendung
D. Nur vor Tests
Meine Antwort:
Frage 34
Wann läuft @PreDestroy?
A. Vor der Bean-Zerstörung
B. Vor der Dependency Injection
C. Vor der Objekterzeugung
D. Vor dem Component Scanning
Meine Antwort:
Frage 35
Was kann BeanPostProcessor?
A. Beans vor und nach der Initialisierung modifizieren oder wrappen
B. Nur Datenbanktabellen erzeugen
C. Nur YAML-Dateien lesen
D. Nur Profile aktivieren
Meine Antwort:
8. Lösungen Mini-Mock-Prüfung
Lösungsschlüssel
1. B
2. B
3. B
4. A
5. B
6. B
7. B
8. B
9. B
10. A
11. A
12. B
13. B
14. B
15. A
16. B
17. A
18. B
19. B
20. A
21. A
22. B
23. A
24. B
25. B
26. B
27. B
28. B
29. A
30. A
31. A
32. A
33. B
34. A
35. A
9. Punkte
Fragen gesamt: 35
Richtige Antworten:
Falsche Antworten:
Punkte:
Punkteberechnung:
richtige Antworten / 35 * 100
Beispiel:
28 / 35 * 100 = 80 %
10. Fehler-Review-Vorlage
Für jede falsche Antwort schreib das:
## Fehler
Fragennummer:
Meine falsche Antwort:
Richtige Antwort:
Warum ich falsch lag:
Richtiges Konzept:
Merksatz:
Beispiel:
## Fehler
Fragennummer: 28
Meine falsche Antwort: A
Richtige Antwort: B
Warum ich falsch lag:
Ich dachte, prototype scope erzeugt bei jedem Methodenaufruf ein neues Objekt.
Richtiges Konzept:
Ein in einen Singleton injizierter Prototype entsteht einmal bei der Erzeugung des Singletons.
Merksatz:
Prototype heißt neu bei Anfrage aus dem Container — nicht neu bei jedem Methodenaufruf.
11. Szenario-Fragen aus der Praxis
Praxisnäher und interview-ähnlich.
Szenario 1 — Direkter @Bean-Aufruf
Code:
@Configuration(proxyBeanMethods = false)
public class AppConfig {
@Bean
public A a() {
return new A();
}
@Bean
public B b() {
return new B(a());
}
}
Frage:
Was ist das Problem?
Meine Antwort:
Musterantwort
Weil proxyBeanMethods = false ist, fängt Spring den direkten Aufruf von a() innerhalb von b() nicht ab. Der Aufruf verhält sich wie ein normaler Java-Methodenaufruf und kann ein separates A-Objekt erzeugen — statt die verwaltete Spring Bean zu nutzen. Besserer Stil:
@Bean
public B b(A a) {
return new B(a);
}
Szenario 2 — Fehlende Properties-Bean
Code:
@ConfigurationProperties(prefix = "jwt")
public record JwtProperties(
String secret,
long expirationMinutes
) {
}
@Service
public class JwtService {
public JwtService(JwtProperties jwtProperties) {
}
}
Fehler:
No qualifying bean of type JwtProperties available
Frage:
Was fehlt wahrscheinlich?
Meine Antwort:
Musterantwort
Die Klasse JwtProperties ist nicht als Spring Bean registriert. Mögliche Fixes:
@ConfigurationPropertiesScan
oder:
@EnableConfigurationProperties(JwtProperties.class)
oder:
@Component
@ConfigurationProperties(prefix = "jwt")
Szenario 3 — Profil-Datei lädt nicht
Datei existiert:
application-prod.yml
Aber Production-Werte werden nicht geladen.
Frage:
Was ist der wahrscheinliche Grund?
Meine Antwort:
Musterantwort
Das prod-Profil ist wahrscheinlich nicht aktiv. application-prod.yml lädt nur, wenn das prod-Profil aktiv ist.
Aktivieren mit:
java -jar app.jar --spring.profiles.active=prod
oder:
SPRING_PROFILES_ACTIVE=prod java -jar app.jar
Szenario 4 — Prototype im Singleton
Code:
@Component
@Scope("prototype")
public class ImportContext {
}
@Service
public class ImportService {
private final ImportContext importContext;
public ImportService(ImportContext importContext) {
this.importContext = importContext;
}
}
Frage:
Bekommt ImportService für jeden Import einen neuen ImportContext?
Meine Antwort:
Musterantwort
Nein. ImportService ist standardmäßig singleton. Spring erzeugt ihn einmal und injiziert beim Erzeugen eine Prototype-ImportContext-Instanz. Dieselbe ImportContext bleibt im Singleton. Für frische Instanzen nutze ObjectProvider<ImportContext>.
Szenario 5 — Request-State im Singleton
Code:
@Service
public class UserService {
private Long currentUserId;
public void process(Long userId) {
this.currentUserId = userId;
}
}
Frage:
Was ist falsch?
Meine Antwort:
Musterantwort
UserService ist standardmäßig singleton und wird über Requests hinweg geteilt. currentUserId ist request-spezifischer, veränderlicher State. Mehrere Requests können ihn überschreiben — falsches Verhalten. Nutze stattdessen Methodenparameter, lokale Variablen oder request-scoped Context.
Szenario 6 — @PostConstruct und Transaktion
Code:
@Service
public class StartupService {
@PostConstruct
public void init() {
runInTransaction();
}
@Transactional
public void runInTransaction() {
// database work
}
}
Frage:
Warum ist das gefährlich?
Meine Antwort:
Musterantwort
init() ruft runInTransaction() in derselben Klasse auf. Das ist Self-Invocation und kann den Spring-Proxy umgehen. Weil @Transactional proxy-basiert ist, wird die Transaktion möglicherweise nicht wie erwartet angewendet. Besser: transaktionale Methode in eine andere Bean verschieben oder ApplicationRunner nutzen.
12. Mündliche Abschlussprüfung Woche 2
Laut antworten.
Frage 1
Erkläre @Configuration und @Bean.
Frage 2
Erkläre, warum vollständige @Configuration-Klassen per Proxy behandelt werden.
Frage 3
Erkläre @Value vs. @ConfigurationProperties.
Frage 4
Erkläre, wie Spring Profile funktionieren.
Frage 5
Erkläre singleton scope.
Frage 6
Erkläre prototype scope.
Frage 7
Erkläre, was passiert, wenn Prototype in Singleton injiziert wird.
Frage 8
Erkläre request scope und scoped proxy.
Frage 9
Erkläre den Bean lifecycle.
Frage 10
Erkläre BeanPostProcessor und warum es wichtig ist.
13. Gute mündliche Antworten
Mündliche Antwort 1 — @Configuration und @Bean
@Configuration markiert eine Klasse als Quelle von Spring Bean-Definitionen. In dieser Klasse liefern mit @Bean annotierte Methoden Objekte, die zu Spring-verwalteten Beans werden. Der Methodenname wird zum Standard-Bean-Namen. Nützlich, wenn du Drittanbieter-Objekte oder Objekte mit eigener Erzeugungslogik brauchst.
Mündliche Antwort 2 — Warum @Configuration per Proxy läuft
Vollständige @Configuration-Klassen werden per Proxy behandelt, damit Spring Aufrufe von @Bean-Methoden abfangen kann. So bleibt Singleton-Verhalten erhalten, wenn eine @Bean-Methode eine andere aufruft. Ohne Proxying wäre ein direkter Aufruf ein normaler Java-Methodenaufruf — und könnte ein neues Objekt erzeugen statt die verwaltete Bean zurückzugeben.
Mündliche Antwort 3 — @Value vs. @ConfigurationProperties
@Value injiziert einen einfachen Konfigurationswert. @ConfigurationProperties bindet eine Gruppe zusammengehöriger Properties an ein Java-Objekt. @ConfigurationProperties ist besser für strukturierte, type-safe, validierte Konfiguration — besonders bei verschachtelten Werten, Listen, Maps oder vielen zusammengehörigen Feldern.
Mündliche Antwort 4 — Profile
Spring Profile erlauben unterschiedliche Beans und Konfiguration in verschiedenen Umgebungen — z. B. dev, test und prod. Ist dev aktiv, lädt Spring application-dev.yml und erzeugt Beans mit @Profile("dev"). Profile aktivierst du per Command-Line-Argumenten, Umgebungsvariablen, IDE-Konfiguration oder @ActiveProfiles in Tests.
Mündliche Antwort 5 — Singleton scope
Singleton ist der Standard-Bean-Scope in Spring. Spring erzeugt eine Bean-Instanz pro Spring-Container und nutzt sie überall wieder. Services und Repositories sind meist singleton. Singleton heißt nicht thread-safe — Singleton-Beans sollten deshalb meist stateless sein und keinen request-spezifischen, veränderlichen State in Feldern speichern.
Mündliche Antwort 6 — Prototype scope
Prototype scope heißt: Spring erzeugt bei jeder Anfrage aus dem Container eine neue Bean-Instanz. Nützlich für kurzlebige, stateful Helper-Objekte. Spring erzeugt und initialisiert Prototype-Beans, verwaltet aber deren Destroy-Lifecycle nicht automatisch.
Mündliche Antwort 7 — Prototype in Singleton
Wird eine Prototype-Bean direkt in eine Singleton-Bean injiziert, entsteht eine Prototype-Instanz, wenn der Singleton erzeugt wird. Der Singleton behält dieselbe Instanz. Bei jedem Methodenaufruf entsteht kein neuer Prototype. Für frische Prototype-Instanzen nutze ObjectProvider, Provider, Lookup-Method-Injection oder einen anderen Lookup-Mechanismus.
Mündliche Antwort 8 — Request scope und scoped proxy
Request scope heißt: eine Bean-Instanz pro HTTP-Request. Hängt ein Singleton-Service von einer request-scoped Bean ab, kann Spring einen scoped proxy injizieren. Der Singleton behält den Proxy; der Proxy delegiert an die echte request-scoped Bean des aktuellen Requests. So können langlebige Beans sicher von kurzlebigen scoped Beans abhängen.
Mündliche Antwort 9 — Bean lifecycle
Der Bean lifecycle ist der Prozess, den Spring beim Erzeugen, Konfigurieren, Initialisieren, Nutzen und Zerstören von Beans durchläuft. Spring liest die Bean-Definition, instanziiert die Bean, injiziert Abhängigkeiten, führt aware callbacks aus, wendet BeanPostProcessors an, läuft Initialisierungs-Callbacks wie @PostConstruct — dann ist die Bean bereit. Beim Schließen des Contexts laufen Destroy-Callbacks wie @PreDestroy für Singleton-Beans.
Mündliche Antwort 10 — BeanPostProcessor
Ein BeanPostProcessor ist ein Spring-Extension Point, der Beans vor und nach der Initialisierung inspizieren, modifizieren oder wrappen kann. Wichtig, weil viele Spring-Features intern Post-Processors nutzen. AOP-Proxies — inklusive Transaktions- oder Security-Proxies — entstehen oft durch BeanPostProcessors.
14. Readiness-Checkliste Woche 2
Vor Woche 3 solltest du alles abhaken können:
[ ] Ich kann @Configuration erklären.
[ ] Ich kann @Bean erklären.
[ ] Ich kenne den Standard-@Bean-Namen.
[ ] Ich kann @Component und @Bean vergleichen.
[ ] Ich weiß, wann ich @Bean nutze.
[ ] Ich kann full configuration mode erklären.
[ ] Ich kann lite configuration mode erklären.
[ ] Ich kann proxyBeanMethods erklären.
[ ] Ich weiß, warum Methodenparameter besser sind als direkte @Bean-Aufrufe.
[ ] Ich kann externe Konfiguration erklären.
[ ] Ich kann application.properties und application.yml vergleichen.
[ ] Ich kann @Value erklären.
[ ] Ich kann @ConfigurationProperties erklären.
[ ] Ich weiß, wie ich @ConfigurationProperties-Klassen registriere.
[ ] Ich kann relaxed binding erklären.
[ ] Ich weiß, warum Secrets nicht committed werden sollten.
[ ] Ich kann Spring Profile erklären.
[ ] Ich weiß, wann application-dev.yml lädt.
[ ] Ich kann @Profile erklären.
[ ] Ich kann @Profile("!prod") erklären.
[ ] Ich kann default profile erklären.
[ ] Ich kann singleton scope erklären.
[ ] Ich kann prototype scope erklären.
[ ] Ich kann request scope erklären.
[ ] Ich kann session scope erklären.
[ ] Ich weiß, was passiert, wenn Prototype in Singleton injiziert wird.
[ ] Ich kann ObjectProvider erklären.
[ ] Ich kann scoped proxy erklären.
[ ] Ich weiß, dass Singleton-Beans meist stateless sein sollten.
[ ] Ich kann @PostConstruct erklären.
[ ] Ich kann @PreDestroy erklären.
[ ] Ich kann BeanPostProcessor erklären.
[ ] Ich weiß, wie BeanPostProcessor mit AOP-Proxies zusammenhängt.
[ ] Ich weiß, dass Spring Prototype-Beans nicht automatisch zerstört.
15. Schwache Themen vor Woche 3
Schreib deine Schwachstellen hier:
## Meine Schwachstellen
1.
2.
3.
4.
5.
Pro Schwachstelle:
## Schwachstelle
Thema:
Warum verwirrend:
Richtige Erklärung:
Code-Beispiel:
Merksatz:
16. Abschluss-Zusammenfassung Woche 2
Woche 2 hat gezeigt: Spring Beans werden nicht nur erzeugt und injiziert.
Sie werden auch:
konfiguriert
per Profile aktiviert
gescoped
initialisiert
post-processed
ggf. per Proxy bereitgestellt
zerstört
Die wichtigsten Ideen:
@Configuration und @Bean definieren Beans per Java-Code.
Externe Konfiguration hält Umgebungswerte außerhalb des Codes.
@ConfigurationProperties ist am besten für gruppierte Config.
Profile aktivieren umgebungsspezifische Beans und Dateien.
Singleton ist der Standard-Scope.
Prototype erzeugt neue Beans nur bei Anfrage aus dem Container.
Request- und session scope sind Web-Scopes.
@PostConstruct und @PreDestroy sind Lifecycle-Callbacks.
BeanPostProcessor kann Beans mit Proxies wrappen.
Verstehst du Woche 2 gut, bist du bereit für Woche 3:
Spring Boot und Auto-Configuration