Mock Full 06 — Spring Professional (60 Fragen)
Prüfungsstil: Spring Professional Develop (2V0-72.22) — vollständiger 60-Fragen-Mock aus gemischten Themen.
Zeitlimit: ca. 130 Minuten (etwa 2 Minuten pro Frage).
Anleitung:
- Wähle pro Frage eine Option und nutze dann Antwort prüfen, um Erklärung und Punktestand zu sehen.
- Mit Zurück und Weiter durch das Set navigieren; deine Auswahl kannst du ändern, bis du prüfst.
- Bei jedem Fehler die Erklärung lesen und einen Merksatz notieren, bevor du weitermachst.
Themenverteilung:
- F1–10: Spring Core & DI
- F11–18: Konfiguration, Profile & Scopes
- F19–28: Spring Boot, Auto-Configuration & Actuator
- F29–36: Spring MVC, REST & Validierung
- F37–44: Datenzugriff, JPA & Transaktionen
- F45–50: Spring Security
- F51–56: Testing
- F57–60: AOP, Events, Async & Observability
Frage 1
Ein Fintech-Team bootstrapped einen CLI-Batch-Job mit ClassPathXmlApplicationContext, während die Web-Schicht AnnotationConfigServletWebServerApplicationContext nutzt.
Welche Aussage über ApplicationContext-Implementierungen und ihre Fähigkeiten ist korrekt?
- A) FileSystemXmlApplicationContext lädt Definitionen vom Dateisystem und unterstützt weiterhin den vollen ApplicationContext-Feature-Satz
- B) Alle ApplicationContext-Typen erzeugen beim Context Refresh eager jeden Prototype-Bean
- C) Nur web-aware Contexts können ApplicationEvent-Instanzen an ApplicationListener-Beans publizieren
- D) GenericApplicationContext kann @Configuration-Klassen registrieren, aber nicht mehr als einmal refreshen
Antwort & Erklärung
Richtige Antwort: A
FileSystemXmlApplicationContext ist ein konkreter ApplicationContext, der Bean-Definitionen vom Dateisystem (nicht Classpath) lädt und Enterprise-Features wie Event-Publikation, Internationalisierung und automatische BeanPostProcessor-Registrierung erbt. Prototype-Beans werden on demand erzeugt, nicht eager beim Refresh. Nicht-Web-Contexts wie AnnotationConfigApplicationContext können Events publizieren. GenericApplicationContext unterstützt in manchen Setups wiederholtes Refresh — der Filesystem-Unterschied ist hier prüfungsrelevant.
Warum die anderen Optionen falsch sind:
- B) Prototype-Beans werden lazy bei erstem getBean oder Injection instanziiert, nicht beim Refresh.
- C) AnnotationConfigApplicationContext und andere Nicht-Web-Contexts publizieren ApplicationEvents normal.
- D) GenericApplicationContext wird oft für programmatische Registrierung genutzt; Refresh-Semantik variiert und ist nicht der unterscheidende Filesystem-Punkt.
Merksatz: „Filesystem-XML-Context = ApplicationContext lädt Definitionen von der Festplatte, nicht vom Classpath."
Weiterlernen: Buchkapitel
Frage 2
LedgerService ist eine Singleton-Komponente mit einem Konstruktor und einem Setter, beide mit @Autowired markiert. Wie injiziert Spring Abhängigkeiten?
@Service
public class LedgerService {
private final AuditPort auditPort;
@Autowired
public LedgerService(AuditPort auditPort) {
this.auditPort = auditPort;
}
@Autowired
public void setMetrics(MetricsClient metrics) {
this.metrics = metrics;
}
private MetricsClient metrics;
}
- A) Spring nutzt Konstruktor-Injection für AuditPort und Setter-Injection für MetricsClient
- B) Konstruktor-Injection läuft zuerst; der Setter wird ignoriert, weil nur ein Injection-Stil erlaubt ist
- C) Spring bricht Startup ab: Mischen von Konstruktor- und Setter-@Autowired auf derselben Klasse ist illegal
- D) Spring injiziert beide Abhängigkeiten über den Konstruktor durch Autowiring der Setter-Parameter
Antwort & Erklärung
Richtige Antwort: A
Spring unterstützt mehrere Injection-Mechanismen auf derselben Klasse. Erforderliche Abhängigkeiten über den Konstruktor werden bei Instanziierung gesetzt; @Autowired-Setter laufen danach während Dependency Injection. Dieser gemischte Stil ist gültig, Konstruktor-only ist aber für erforderliche unveränderliche Felder bevorzugt.
Warum die anderen Optionen falsch sind:
- B) Setter-@Autowired wird nicht ignoriert; er wird nach Objektkonstruktion verarbeitet.
- C) Mischen von Konstruktor- und Setter-Injection wird vollständig unterstützt.
- D) Setter werden nicht in Konstruktor-Autowiring gefaltet; sie sind separate Injection Points.
Merksatz: „Konstruktor verdrahtet zuerst, dann @Autowired-Setter — beides kann auf einem Bean koexistieren."
Weiterlernen: Buchkapitel
Frage 3
InventoryService hängt von CacheProvider ab. Zwei Beans existieren: redisCacheProvider (@Primary) und caffeineCacheProvider (@Qualifier("local")).
Der Konstruktorparameter ist mit @Qualifier("local") CacheProvider cache annotiert. Welcher Bean wird injiziert?
- A) caffeineCacheProvider, weil @Qualifier am Injection Point @Primary überschreibt
- B) @Primary redisCacheProvider, weil @Primary immer @Qualifier schlägt
- C) Startup schlägt mit NoUniqueBeanDefinitionException fehl
- D) Ein neuer anonymer CacheProvider-Proxy, der beide Implementierungen kombiniert
Antwort & Erklärung
Richtige Antwort: A
@Qualifier am Injection Point wählt einen spezifischen Bean nach Name oder Custom-Qualifier-Wert. Er hat Vorrang vor @Primary für diesen Injection Site. @Primary gilt nur, wenn kein Qualifier die Abhängigkeit auflöst.
Warum die anderen Optionen falsch sind:
- B) @Primary ist der Default bei Mehrdeutigkeit; expliziter @Qualifier überschreibt ihn.
- C) Der Qualifier löst die Mehrdeutigkeit; Startup gelingt.
- D) Spring merged mehrere Beans nicht zu einem Composite, außer eine Custom Factory tut das.
Merksatz: „@Qualifier am Injection Point schlägt @Primary für diese Abhängigkeit."
Weiterlernen: Buchkapitel
Frage 4
Formatter ist prototype-scoped. ReportExporter ist Singleton. Was liefert ObjectProvider<Formatter> dem Singleton?
@Component
public class ReportExporter {
@Autowired
private ObjectProvider<Formatter> formatterProvider;
}
- A) Einen lazy Handle, um on demand eine neue oder bestehende Formatter-Instanz zu holen, ohne eager Prototype-Erzeugung beim Singleton-Startup
- B) Einen Compile-Time-Fehler, weil ObjectProvider keine Prototype-Beans wrappen kann
- C) Dieselbe Prototype-Instanz, für immer im Singleton gecacht
- D) Automatische @Lookup-Method-Semantik ohne @Lookup-Deklaration
Antwort & Erklärung
Richtige Antwort: A
ObjectProvider ist eine Factory-Abstraktion, die Dependency Resolution verzögert. Für Prototype-Beans in Singletons vermeidet es frühe Instanziierung und erlaubt getObject(), wenn eine frische Instanz gebraucht wird. Idiomatische Alternative zu @Lookup für optionale oder scoped Dependencies.
Warum die anderen Optionen falsch sind:
- B) ObjectProvider ist genau für optionale, multiple oder scoped Bean-Retrieval designed.
- C) Jedes getObject() für einen Prototype liefert eine eigene Instanz, sofern Scope nicht anders.
- D) ObjectProvider ist verwandt, aber nicht identisch mit @Lookup; es ist ein injizierter Provider-Handle.
Merksatz: „ObjectProvider = verzögerte Factory für scoped, optionale oder multiple Kandidaten."
Weiterlernen: Buchkapitel
Frage 5
Eine @Bean-Methode liefert bei jedem Aufruf eine neue DataSource. Eine andere @Configuration-Klasse @Import`t die erste. Wie viele DataSource-Instanzen existieren im Container?
@Configuration
public class InfraConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
}
@Configuration
@Import(InfraConfig.class)
public class AppConfig { }
- A) Eine Singleton-DataSource, weil @Bean-Methoden in @Configuration geproxied und abgefangen werden
- B) Zwei Instanzen, weil @Import Beans immer dupliziert
- C) Null, sofern kein @Component explizit DataSource @Autowired
- D) Eine pro Injection Point, ähnlich Prototype-Scope
Antwort & Erklärung
Richtige Antwort: A
@Configuration-Klassen sind full-mode geproxied, sodass @Bean-Method-Interceptions denselben Singleton-Bean aus dem Container zurückgeben, wenn die Methode erneut aufgerufen wird. @Import registriert die importierte Configuration ohne Singleton-Semantik zu duplizieren.
Warum die anderen Optionen falsch sind:
- B) @Import bringt Definitionen rein; es dupliziert keine Singleton-Beans.
- C) @Bean registriert eine Bean-Definition unabhängig von Injection-Bedarf.
- D) Default-@Bean-Scope ist Singleton (einer pro Bean-Name), nicht pro Injection Point.
Merksatz: „Full @Configuration proxied @Bean-Methoden — wiederholte Aufrufe liefern denselben Singleton."
Weiterlernen: Buchkapitel
Frage 6
Ein Entwickler fügt @Component zu einer abstrakten BaseProcessor und @Component zu konkretem CsvProcessor hinzu, der sie erweitert.
Was wird bei Default Component Scanning registriert?
- A) Nur CsvProcessor; abstrakte @Component-Klassen werden nicht als Beans instanziiert
- B) Sowohl BaseProcessor- als auch CsvProcessor-Beans
- C) Keines, weil Vererbung Stereotyp-Erkennung bricht
- D) Ein einzelner Bean mit dem Superklassen-Namen baseProcessor
Antwort & Erklärung
Richtige Antwort: A
Abstrakte Klassen mit @Component werden als Kandidaten erkannt, können aber nicht instanziiert werden. Konkrete Subklassen wie CsvProcessor werden als Beans registriert. Der abstrakte Parent ist kein eigenständiger Bean im Container.
Warum die anderen Optionen falsch sind:
- B) Abstrakte Klassen können nicht instanziiert werden; Spring überspringt Bean-Erzeugung für den abstrakten Typ.
- C) Vererbung bricht Scanning nicht; konkrete Subklassen werden weiterhin gefunden.
- D) Für die abstrakte Klasse selbst wird kein Bean erzeugt.
Merksatz: „Abstrakte @Component-Typen werden nicht instanziiert; konkrete Subklassen werden Beans."
Weiterlernen: Buchkapitel
Frage 7
Kein @Primary oder @Qualifier ist vorhanden. Was passiert beim Startup?
public interface PaymentPort { }
@Component("legacy")
public class LegacyPaymentAdapter implements PaymentPort { }
@Component("modern")
public class ModernPaymentAdapter implements PaymentPort { }
@Service
public class CheckoutService {
public CheckoutService(PaymentPort port) { }
}
- A) Startup schlägt mit NoUniqueBeanDefinitionException für PaymentPort fehl
- B) Spring injiziert legacy, weil @Component("legacy") alphabetisch zuerst sortiert
- C) Spring injiziert modern, weil es per Konvention die Default-Implementierung ist
- D) Spring erzeugt einen JDK-Dynamic-Proxy, der PaymentPort implementiert und an beide Adapter delegiert
Antwort & Erklärung
Richtige Antwort: A
Wenn mehrere Beans zu einem Injection Point passen und kein @Qualifier, @Primary oder @Resource-Name-Match die Mehrdeutigkeit auflöst, wirft Spring NoUniqueBeanDefinitionException beim Startup. Alphabetische Bean-Namen oder Konventionen gelten nicht.
Warum die anderen Optionen falsch sind:
- B) Bean-Name-Reihenfolge ist keine Disambiguierungsregel.
- C) Es gibt keine „Default-Implementierung"-Konvention ohne @Primary.
- D) Spring komponiert nicht automatisch mehrere Beans zu einem Proxy, sofern nicht konfiguriert.
Merksatz: „Zwei Beans, ein Typ, kein Qualifier → NoUniqueBeanDefinitionException."
Weiterlernen: Buchkapitel
Frage 8
Welche Aussage über den Spring-IoC-Container und Dependency Graphs ist korrekt?
- A) Der Container kann einige zirkuläre Abhängigkeiten für Singletons mit früh exponierten Referenzen oder Setter-Injection auflösen
- B) Zirkuläre Abhängigkeiten zwischen Singleton-Setter-Injections schlagen in jeder Spring-Version bedingungslos fehl
- C) Prototype-Beans in Zyklen werden immer mit Konstruktor-Injection-Retries aufgelöst
- D) Zirkuläre Abhängigkeiten werden nur zur Laufzeit beim ersten getBean erkannt, nie beim Context Refresh
Antwort & Erklärung
Richtige Antwort: A
Spring kann bestimmte Singleton-Zyklen brechen, indem ein teilweise initialisierter Bean früh exponiert wird (Singleton Factory) oder durch Setter/Field Injection, wo das Objekt existiert, bevor Dependencies gesetzt werden. Konstruktor-only-Zyklen unter Singletons schlagen typischerweise fehl. Prototype-Zyklen sind problematisch, weil jedes Mal eine neue Instanz nötig ist.
Warum die anderen Optionen falsch sind:
- B) Setter/Field-Zyklen unter Singletons können gelingen; Konstruktor-only-Zyklen meist nicht.
- C) Prototype-Beteiligung an Zyklen scheitert häufig; Konstruktor-Retries werden nicht genutzt.
- D) Viele Zirkularitätsfehler treten beim Context Refresh auf, nicht lazy beim ersten Zugriff.
Merksatz: „Singleton-Setter-Zyklen können funktionieren; Konstruktor-only-Singleton-Zyklen meist nicht."
Weiterlernen: Buchkapitel
Frage 9
Angenommen lite @Configuration-Mode (kein CGLIB-Proxy): Wie viele XmlParser-Instanzen entstehen, wenn jsonParser() erstmals angefordert wird?
@Configuration
public class ParserConfig {
@Bean
public JsonParser jsonParser() {
return new JsonParser(xmlParser());
}
@Bean
public XmlParser xmlParser() {
return new XmlParser();
}
}
- A) Zwei XmlParser-Instanzen: eine container-verwaltete Bean und eine innerhalb jsonParser() erzeugte
- B) Eine gemeinsame XmlParser-Bean, die beide @Bean-Methoden nutzen
- C) Null; lite mode deaktiviert @Bean-Registrierung
- D) Eine XmlParser pro Application Refresh nur mit @Scope("prototype")
Antwort & Erklärung
Richtige Antwort: A
In lite @Configuration (oder @Bean-Methoden auf Nicht-@Configuration-Klassen) sind @Bean-Methoden plain method calls. xmlParser() innerhalb jsonParser() erzeugt ein separates Objekt, das nicht als gemeinsamer Singleton-Bean verwaltet wird. Full @Configuration Proxy Mode fängt Aufrufe ab und liefert den Container-Bean.
Warum die anderen Optionen falsch sind:
- B) Ohne Proxy-Interception umgehen direkte Methodenaufrufe den Container-Singleton.
- C) Lite Mode registriert weiterhin @Bean-Definitionen; er überspringt nur Configuration-Class-Subclass-Proxying.
- D) Scope ist standardmäßig Singleton pro Bean-Name, aber der direkte Aufruf erzeugt trotzdem eine Extra-Instanz.
Merksatz: „Lite @Configuration: direkte @Bean-Methodenaufrufe können Extra-Instanzen erzeugen."
Weiterlernen: Buchkapitel
Frage 10
Ein Team entfernt alle Spring-Annotationen und ruft manuell new ServiceA(new ServiceB()) in main() auf.
Welches Problem, das Spring DI löst, tritt zuerst in Integrationstests wieder auf?
- A) Unfähigkeit, Collaborators mit Test-Doubles zu tauschen, ohne Production-Construction-Code zu ändern
- B) Verlust von Internationalisierungs-Support im IoC-Container
- C) Fehlende automatische Actuator-Endpoints
- D) Deaktivierte @Transactional-Verarbeitung auf main()
Antwort & Erklärung
Richtige Antwort: A
Manuelle Konstruktion koppelt Klassen eng an konkrete Implementierungen — Mocks oder Stubs in Tests sind schwer substituierbar. Spring DI externalisiert Object-Graph-Assembly, sodass Tests Beans via @MockBean, @TestConfiguration oder alternative Contexts ersetzen können.
Warum die anderen Optionen falsch sind:
- B) i18n ist unabhängig vom unmittelbaren Test-Schmerz bei manuellem new-Wiring.
- C) Actuator ist Spring-Boot-Thema, nicht das erste DI-Regressionsproblem.
- D) @Transactional braucht Spring Management; es ist nicht das beschriebene „erste" DI-Problem.
Merksatz: „Manuelles new() koppelt an konkrete Typen und blockiert einfache Test-Doubles."
Weiterlernen: Buchkapitel
Frage 11
shipping.max-weight-kg=30 und shipping.sla=PT2H stehen in application.yml. ShippingProps ist ein @ConfigurationProperties-Record ohne @Component. Was ist für Binding nötig?
@ConfigurationProperties(prefix = "shipping")
public record ShippingProps(int maxWeightKg, Duration sla) { }
@RestController
public class QuoteController {
public QuoteController(ShippingProps props) { }
}
- A) ShippingProps via @EnableConfigurationProperties(ShippingProps.class) oder @ConfigurationPropertiesScan registrieren
- B) @Value auf jede Record-Komponente; @ConfigurationProperties bindet keine Records
- C) Records können keine Beans sein; in Klasse mit Settern umwandeln
- D) Binding funktioniert automatisch für jeden Record auf dem Classpath ohne Registrierung
Antwort & Erklärung
Richtige Antwort: A
@ConfigurationProperties-Typen müssen als Beans registriert werden via @EnableConfigurationProperties, @ConfigurationPropertiesScan oder Stereotyp-Registrierung. Danach bindet Boot kebab-case Properties an Record-Komponenten. @Value ist pro Feld und nicht das ConfigurationProperties-Modell.
Warum die anderen Optionen falsch sind:
- B) @ConfigurationProperties bindet immutable Records bei Registrierung; @Value ist unnötig.
- C) Records werden in modernem Spring Boot als @ConfigurationProperties-Beans unterstützt.
- D) Registrierung ist nötig; Classpath-Allein reicht nicht.
Merksatz: „ConfigurationProperties-Typen brauchen explizites Enablement/Scan — Records inklusive."
Weiterlernen: Buchkapitel
Frage 12
Ein Bean ist mit @Profile("!integration & cloud") annotiert und aktive Profile sind integration,cloud.
Wird der Bean registriert?
- A) Nein, weil der Ausdruck ein Profil verlangt, das nicht integration ist UND cloud enthält; mit beiden aktiv schlägt die negierte Klausel fehl
- B) Ja, weil negierte Profile aktive aufheben
- C) Ja, Profile-Ausdrücke werden ignoriert, wenn mehrere Profile aktiv sind
- D) Nur im Default-Profil
Antwort & Erklärung
Richtige Antwort: A
@Profile unterstützt Ausdrücke. „!integration & cloud" bedeutet: nicht integration UND cloud müssen gelten. Mit aktiven Profilen integration und cloud ist !integration false — der ganze Ausdruck ist false und der Bean wird nicht registriert.
Warum die anderen Optionen falsch sind:
- B) Negation „hebt" ein aktives Profil in einem AND-Ausdruck nicht auf; alle Teile müssen passen.
- C) Profile-Ausdrücke werden mit aktiven Profil-Sets evaluiert.
- D) Default-Profil ist unabhängig von expliziten aktiven Profilen integration und cloud.
Merksatz: „!integration & cloud scheitert, wenn integration unter aktiven Profilen ist."
Weiterlernen: Buchkapitel
Frage 13
TraceService ist Singleton. RequestIdHolder ist request-scoped mit TARGET_CLASS-Proxy. Was hält TraceService tatsächlich?
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestIdHolder {
private String requestId;
public void setRequestId(String id) { this.requestId = id; }
public String getRequestId() { return requestId; }
}
@Service
public class TraceService {
private final RequestIdHolder holder;
public TraceService(RequestIdHolder holder) { this.holder = holder; }
}
- A) Einen CGLIB-Proxy, der jeden Methodenaufruf an den aktuellen request-scoped Bean delegiert
- B) Eine direkte request-scoped Instanz, die über alle HTTP-Requests geteilt wird
- C) Einen neuen RequestIdHolder pro TraceService-Methodenaufruf automatisch
- D) Compile-Fehler, weil Singletons nicht von request-scoped Beans abhängen dürfen
Antwort & Erklärung
Richtige Antwort: A
Injection eines kürzer lebenden Scopes in einen Singleton erfordert einen Scoped Proxy. TARGET_CLASS erzeugt einen CGLIB-Proxy, der den echten Request-Bean pro Thread/Request bei Methodenaufrufen nachschlägt — korrekte Lifecycle-Semantik bleibt erhalten.
Warum die anderen Optionen falsch sind:
- B) Eine direkte Instanz wäre eine pro Singleton und bräche Request-Isolation.
- C) Proxies delegieren pro Aufruf an das scoped Target, nicht automatisch pro TraceService-Methode.
- D) Dieses Muster ist gültig und üblich mit Scoped Proxies.
Merksatz: „Request-Bean in Singleton → Scoped CGLIB-Proxy delegiert pro Request."
Weiterlernen: Buchkapitel
Frage 14
Eine @Bean-Methode deklariert @Scope("prototype") und wird von einer anderen @Bean-Methode in derselben full @Configuration-Klasse aufgerufen. Wie viele Prototype-Instanzen verwaltet der Container bei Aufrufen über den Proxy?
- A) Jeder abgefangene @Bean-Methodenaufruf über den Proxy liefert die container-verwaltete Prototype-Instanz für diesen Bean-Namen, aber interne direkte Aufrufe können den Proxy umgehen
- B) Immer eine, weil @Configuration-Proxies Prototype-Aufrufe kollabieren
- C) Prototype-Scope wird innerhalb @Configuration-Klassen zu Singleton hochgestuft
- D) Null; Prototypes müssen @Component-Typen sein
Antwort & Erklärung
Richtige Antwort: A
Full @Configuration proxied @Bean-Methodenaufrufe von anderen @Bean-Methoden und leitet über den Container — Prototype-Beans erzeugen weiterhin eine neue Instanz pro getBean/abgefangenem Aufruf. Die Falle sind direkte Java-Aufrufe auf this (lite mode), die Interception umgehen.
Warum die anderen Optionen falsch sind:
- B) Abgefangene Prototype-@Bean-Aufrufe liefern weiterhin distinct Instanzen pro Invocation.
- C) Scope wird nicht hochgestuft; Proxy sichert Container-Semantik.
- D) @Bean-Methoden können Prototype-Scope deklarieren.
Merksatz: „Full @Configuration fängt @Bean-Aufrufe ab — Prototype bleibt neu pro abgefangenem Aufruf."
Weiterlernen: Buchkapitel
Frage 15
In einer laufenden Spring-Boot-App: Wann werden diese Callbacks relativ zu @PreDestroy auf einem anderen Bean aufgerufen?
@Component
public class WarmupRunner implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() { /* connect pool */ }
@Override
public void destroy() { /* close pool */ }
}
- A) afterPropertiesSet läuft, nachdem alle Beans existieren; DisposableBean.destroy läuft beim Context Shutdown in umgekehrter Abhängigkeitsreihenfolge grob
- B) Beide laufen, bevor irgendein Konstruktor fertig ist
- C) destroy läuft vor afterPropertiesSet beim Refresh
- D) InitializingBean ersetzt @PostConstruct und verhindert @PreDestroy
Antwort & Erklärung
Richtige Antwort: A
InitializingBean.afterPropertiesSet läuft nach Dependency Injection für diesen Bean. DisposableBean.destroy und @PreDestroy-Methoden laufen beim Context Shutdown, grob in umgekehrter Abhängigkeitsreihenfolge. Sie sind komplementäre Lifecycle-Hooks, nicht gegenseitig ausschließend.
Warum die anderen Optionen falsch sind:
- B) Initialization-Callbacks laufen nach Konstruktion und Injection.
- C) destroy ist ein Shutdown-Hook, nicht Teil der Refresh-Init-Reihenfolge vor afterPropertiesSet.
- D) @PreDestroy läuft weiter; Interfaces deaktivieren annotation-basiertes Lifecycle nicht.
Merksatz: „afterPropertiesSet nach Injection; destroy/@PreDestroy beim Shutdown."
Weiterlernen: Buchkapitel
Frage 16
application.properties setzt spring.profiles.active=dev und spring.config.activate.on-profile=dev auf einem verschachtelten Dokument in application-dev.yml.
Was trifft auf die Property-Loading-Reihenfolge zu?
- A) application.properties überschreibt immer profile-spezifisches YAML unabhängig von der Reihenfolge
- B) Profile-spezifische Dateien laden, wenn das Profil aktiv ist; spätere Quellen in Spring-Boot-Property-Precedence können frühere überschreiben
- C) spring.config.activate.on-profile ersetzt spring.profiles.active vollständig
- D) YAML und Properties können nicht in derselben Boot-App koexistieren
Antwort & Erklärung
Richtige Antwort: B
Spring Boot lädt profile-spezifische Dokumente, wenn Profile aktiv sind. Property-Precedence folgt geordneten Property Sources: Command Line, OS Env, profile-spezifische Dateien, application.properties, Defaults usw. Spätere höherwertige Quellen überschreiben frühere Werte.
Warum die anderen Optionen falsch sind:
- A) Precedence ist nicht „Properties gewinnen immer"; es hängt von Quellenreihenfolge und Regeln ab.
- C) activate.on-profile gated Dokumente; es ersetzt nicht den Profilaktivierungsmechanismus.
- D) Boot unterstützt YAML und Properties zusammen.
Merksatz: „Aktive Profil-Dateien laden bedingt; Precedence entscheidet Overrides."
Weiterlernen: Buchkapitel
Frage 17
Welche Technologie löst diese Injection auf?
@Value("#{systemProperties['user.timezone']}")
private String timezone;
- A) Nur PropertySourcesPlaceholderConfigurer
- B) Spring Expression Language (SpEL) eingebettet in @Value
- C) JNDI-Lookup im Application Server
- D) Automatisches @ConfigurationProperties-Binding
Antwort & Erklärung
Richtige Antwort: B
Die #\{expression\}-Syntax in @Value bedeutet SpEL-Evaluation. systemProperties ist eine SpEL-Variable, die JVM-System-Properties exponiert. Plain $\{property\} wäre Property-Placeholder-Auflösung ohne SpEL.
Warum die anderen Optionen falsch sind:
- A) PlaceholderConfigurer behandelt
$\{property\};#\{expression\}ist SpEL via StandardBeanExpressionResolver. - C) Kein JNDI in diesem Ausdruck.
- D) @ConfigurationProperties ist unabhängig von inline SpEL @Value.
Merksatz: „@Value #\{expression\} = SpEL; $\{property\} = Property-Placeholder."
Weiterlernen: Buchkapitel
Frage 18
@Bean public static BeanFactoryPostProcessor registrar() { return beanFactory -> { }; } muss static sein. Warum?
- A) Statische Methoden erzeugen automatisch Prototype-Beans
- B) Statische @Bean-Methoden werden früh beim Context Parsing aufgerufen, bevor reguläre @Configuration-Instanz-Beans erzeugt werden — ermöglicht BeanFactoryPostProcessor-Registrierung
- C) Nicht-statische BFPP-@Bean-Methoden erzeugen Zirkularität mit der Configuration-Instanz
- D) Nur statische Methoden können @Profile auf @Bean-Methoden nutzen
Antwort & Erklärung
Richtige Antwort: B
BeanFactoryPostProcessor-Beans müssen registriert werden, bevor Bean-Definitionen vollständig verarbeitet sind. Statische @Bean-Methoden auf @Configuration-Klassen werden ohne Instanziierung des @Configuration-Objekts aufgerufen — frühe Registrierung sichergestellt. Nicht-statische BFPP-@Bean-Methoden können funktionieren, werden aber evtl. verzögert — Ordering-Probleme.
Warum die anderen Optionen falsch sind:
- A) Static impliziert keinen Prototype-Scope.
- C) Das Problem ist Lifecycle-Ordering, keine generische Zirkularitätsregel.
- D) @Profile ist nicht auf statische @Bean-Methoden beschränkt.
Merksatz: „Statischer @Bean BFPP = frühe Registrierung, bevor Configuration-Instanz existiert."
Weiterlernen: Buchkapitel
Frage 19
Eine Library liefert META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports mit Eintrag com.acme.MetricsAutoConfiguration.
Wie lädt Spring Boot 3 diese Auto-Configuration?
- A) Nur über spring.factories EnableAutoConfiguration-Key
- B) Über den AutoConfiguration.imports-Mechanismus, verarbeitet von AutoConfigurationImportSelector
- C) Via @Import auf @SpringBootApplication, das die Datei zur Laufzeit direkt liest
- D) Nur wenn der User manuell @Import(MetricsAutoConfiguration.class) hinzufügt
Antwort & Erklärung
Richtige Antwort: B
Spring Boot 2.7+ und Boot 3 nutzen META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports zur Registrierung von Auto-Configuration-Klassen. AutoConfigurationImportSelector lädt sie, wenn @EnableAutoConfiguration (Meta auf @SpringBootApplication) vorhanden ist.
Warum die anderen Optionen falsch sind:
- A) spring.factories EnableAutoConfiguration ist legacy; imports file ist der Boot-3-Pfad.
- C) @SpringBootApplication aktiviert Auto-Config über Selectors, nicht direktes File-Parsing im User-Code.
- D) Library Auto-Config soll automatisch laden ohne manuelles @Import.
Merksatz: „Boot 3 Auto-Config-Klassen stehen in AutoConfiguration.imports."
Weiterlernen: Buchkapitel
Frage 20
Jedis ist auf dem Classpath und die Anwendung definiert einen eigenen RedisTemplate-Bean. Was passiert?
@ConditionalOnClass(name = "redis.clients.jedis.Jedis")
@ConditionalOnMissingBean(RedisTemplate.class)
public class RedisAutoConfiguration {
@Bean RedisTemplate<String, String> redisTemplate() { return new RedisTemplate<>(); }
}
- A) Beide RedisTemplate-Beans registrieren und @Primary ist erforderlich
- B) RedisAutoConfiguration tritt zurück, weil @ConditionalOnMissingBean einen bestehenden RedisTemplate findet
- C) Auto-Configuration überschreibt den User-Bean, weil sie zuerst lädt
- D) Anwendung schlägt fehl, weil doppelte Bean-Namen illegal sind
Antwort & Erklärung
Richtige Antwort: B
@ConditionalOnMissingBean verhindert, dass Auto-Config einen Bean registriert, wenn der User bereits einen dieses Typs definiert hat. Das ist das Back-off-Pattern für User-Overrides. @ConditionalOnClass stellt sicher, dass Redis-Support nur bei Jedis auf dem Classpath in Betracht gezogen wird.
Warum die anderen Optionen falsch sind:
- A) Back-off vermeidet doppelte Beans; kein @Primary-Kampf.
- C) User-Beans haben generell Vorrang; Auto-Config ist bedingt.
- D) Back-off verhindert doppelte Registrierung und Fehler.
Merksatz: „OnMissingBean = Auto-Config tritt zurück, wenn User-Bean existiert."
Weiterlernen: Buchkapitel
Frage 21
management.endpoints.web.exposure.include=health,info,metrics und management.endpoint.health.show-details=when_authorized. Ein unauthentifizierter GET /actuator/health wird gesendet. Was ist typisch?
- A) Vollständige Komponenten-Details für Disk Space und Database erscheinen immer
- B) Aggregierter Health-Status erscheint; detaillierte Komponenten können ohne Authorization verborgen sein
- C) 404, weil health separat mit management.endpoint.health.enabled=true in allen Versionen aktiviert werden muss
- D) Response ist immer leeres JSON
Antwort & Erklärung
Richtige Antwort: B
Health über Web Exposure exponiert den Endpoint. show-details=when_authorized unterdrückt detaillierte Komponenten für unauthentifizierte Aufrufer, liefert aber weiterhin Top-Level-Status (UP/DOWN). Authorization-Regeln hängen von Spring Security ab, wenn vorhanden.
Warum die anderen Optionen falsch sind:
- A) Details sind durch show-details-Policy für anonyme Nutzer eingeschränkt.
- C) In der Exposure-Liste enthalten aktiviert Web-Zugriff; separates enabled-Flag defaultet true.
- D) Health liefert Status-Information, keinen leeren Body.
Merksatz: „show-details=when_authorized verbirgt Komponenten-Details vor anonymen Aufrufern."
Weiterlernen: Buchkapitel
Frage 22
Welche Annotationen sind standardmäßig meta-annotiert auf @SpringBootApplication?
@SpringBootApplication
public class ShopApplication {
public static void main(String[] args) {
SpringApplication.run(ShopApplication.class, args);
}
}
- A) @EnableWebMvc, @EnableJpaRepositories und @EnableScheduling
- B) @EnableAutoConfiguration, @ComponentScan und @Configuration
- C) Nur @SpringBootConfiguration
- D) @ImportAutoConfiguration und @EnableActuator
Antwort & Erklärung
Richtige Antwort: B
@SpringBootApplication setzt sich zusammen aus @SpringBootConfiguration (spezialisiertes @Configuration), @EnableAutoConfiguration und @ComponentScan. Es aktiviert nicht automatisch @EnableWebMvc, JPA Repositories, Scheduling oder Actuator.
Warum die anderen Optionen falsch sind:
- A) Diese Fähigkeiten kommen von Startern und zusätzlichen Annotationen oder Auto-Config, nicht von @SpringBootApplication selbst.
- C) Es umfasst mehr als nur @SpringBootConfiguration.
- D) Keine @EnableActuator-Meta-Annotation auf @SpringBootApplication.
Merksatz: „@SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan."
Weiterlernen: Buchkapitel
Frage 23
spring.main.lazy-initialization=true ist für ein großes Monolith während der Entwicklung gesetzt.
Was ist die bedeutendste Verhaltensänderung?
- A) Alle @Bean-Methoden werden prototype-scoped
- B) Singleton-Beans werden bei erstem Bedarf erzeugt statt eager beim Context Refresh (mit Ausnahmen wie Infrastructure Beans)
- C) Actuator-Endpoints werden automatisch deaktiviert
- D) @Transactional funktioniert auf lazy Beans nicht mehr
Antwort & Erklärung
Richtige Antwort: B
Lazy Initialization verzögert Singleton-Erzeugung bis zur ersten Dependency Injection oder explizitem getBean — schnellerer Startup in der Entwicklung. Infrastructure Beans und manche Boot-Internals können weiter eager initialisieren. @Transactional und Actuator werden nicht global deaktiviert.
Warum die anderen Optionen falsch sind:
- A) Lazy Initialization ändert Timing, nicht Scope.
- C) Actuator bleibt verfügbar, wenn auf Classpath und konfiguriert.
- D) Transaction Management gilt bei Bean-Aufrufen, nicht nur bei Erzeugungszeitpunkt.
Merksatz: „lazy-initialization=true verzögert Singleton-Erzeugung bis zur ersten Nutzung."
Weiterlernen: Buchkapitel
Frage 24
Ein custom HealthIndicator liefert Health.down().withDetail("queue", "stalled").build(). diskSpaceHealthIndicator meldet UP. Wie ist der composite /actuator/health-Status?
- A) UP, weil die Mehrheit der Indikatoren UP ist
- B) DOWN, weil jeder HealthIndicator mit DOWN den Aggregat-Status auf DOWN zieht
- C) UNKNOWN immer, wenn Details vorhanden sind
- D) OUT_OF_SERVICE nur wenn management.health.defaults.enabled=false
Antwort & Erklärung
Richtige Antwort: B
Spring Boot HealthContributorRegistry aggregiert Contributors. Wenn ein Teilnehmer DOWN ist, wird der Gesamt-Health-Status DOWN — sofern nicht anders konfiguriert. Details hängen pro Contributor, ändern aber nicht die Aggregationsregel.
Warum die anderen Optionen falsch sind:
- A) Health-Aggregation ist keine demokratische Mehrheitsabstimmung.
- C) Details erzwingen kein UNKNOWN.
- D) OUT_OF_SERVICE ist ein eigener Status, nicht an diese Property in diesem Szenario gebunden.
Merksatz: „Jeder DOWN-Contributor zieht composite /actuator/health auf DOWN."
Weiterlernen: Buchkapitel
Frage 25
Wann führt ApplicationRunner.run relativ zum fertigen Context aus?
public class AuditApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
// seed reference data
}
}
- A) Bevor irgendein Bean erzeugt wird
- B) Nachdem der ApplicationContext vollständig refreshed ist, aber bevor die Anwendung Readiness signalisiert (Teil der Startup-Callbacks)
- C) Nur bei SIGTERM Shutdown
- D) Nur wenn @PostConstruct auf derselben Klasse zuerst fertig ist, falls beides existiert
Antwort & Erklärung
Richtige Antwort: B
ApplicationRunner und CommandLineRunner-Beans laufen nach Context Refresh während Application Startup, geordnet mit @Order. Sie laufen nach Bean-Initialisierung — geeignet für Startup-Tasks mit ApplicationArguments.
Warum die anderen Optionen falsch sind:
- A) Beans müssen existieren; Runner sind Beans, die nach Refresh aufgerufen werden.
- C) Runner sind Startup-Hooks, keine Shutdown-Hooks.
- D) @PostConstruct auf demselben Bean läuft vor run(); beides kann mit unterschiedlichem Timing koexistieren.
Merksatz: „ApplicationRunner läuft nach Context Refresh beim Startup."
Weiterlernen: Buchkapitel
Frage 26
spring-boot-starter-web bringt spring-boot-starter-tomcat transitiv. Das Team excludiert Tomcat und fügt spring-boot-starter-jetty hinzu. Was bleibt wahr?
- A) @SpringBootApplication deaktiviert Servlet Auto-Configuration automatisch
- B) ServletWebServerFactory Auto-Configuration wählt Jetty, wenn Tomcat fehlt und Jetty auf dem Classpath ist
- C) Die App wird eine nicht-web Reactive Application
- D) DispatcherServlet wird nicht mehr registriert
Antwort & Erklärung
Richtige Antwort: B
Spring Boot Servlet Web Auto-Configuration ist bedingt auf verfügbare embedded Server Implementierungen. Tomcat excludieren und Jetty hinzufügen lässt JettyServletWebServerFactory Auto-Config Tomcat zurücktreten und Jetty nutzen. Es bleibt ein Servlet Stack mit DispatcherServlet.
Warum die anderen Optionen falsch sind:
- A) Web Auto-Config bleibt für Servlet Stacks mit embedded Server.
- C) Jetty unterstützt Servlet MVC; das ist kein WebFlux-Switch allein.
- D) DispatcherServlet ist weiterhin Teil von spring-boot-starter-web.
Merksatz: „Embedded Server per Starter Exclusions tauschen; Servlet MVC bleibt."
Weiterlernen: Buchkapitel
Frage 27
Entwickler führt java -jar app.jar --debug aus und setzt logging.level.org.springframework.boot.autoconfigure=DEBUG.
Welches zusätzliche Startup-Artefakt hilft bei Auto-Configuration-Entscheidungen?
- A) Ein Heap Dump nach /tmp
- B) Auto-Configuration-Report mit matched und negative @Conditional-Evaluations
- C) Automatisches Rollback aller @Bean-Definitionen
- D) Deaktivierung von @ConditionalOnProperty-Checks
Antwort & Erklärung
Richtige Antwort: B
Boot kann einen Auto-Configuration-Report bei DEBUG/TRACE für org.springframework.boot.autoconfigure loggen — welche Configurations matched, nicht matched und excluded. --debug triggert auch einen Condition-Evaluation-Report in der Konsole.
Warum die anderen Optionen falsch sind:
- A) Debug erzeugt keine Heap Dumps.
- C) Reports sind nur diagnostisch; sie rollbacken keine Beans.
- D) Condition Evaluation läuft weiter; Logging zeigt Ergebnisse.
Merksatz: „DEBUG Auto-Config Package → Condition Match/Negative Report beim Startup."
Weiterlernen: Buchkapitel
Frage 28
micrometer-registry-prometheus ist auf dem Classpath und management.endpoints.web.exposure.include=prometheus. Wo werden Metriken exponiert?
- A) Nur via JMX, sofern nicht explizit deaktiviert
- B) Unter /actuator/prometheus als Scrape-Endpoint zusätzlich zur allgemeinen Metrics-Infrastruktur
- C) Nur innerhalb /actuator/health
- D) Prometheus-Format erfordert immer Ersatz von Actuator durch custom Controller
Antwort & Erklärung
Richtige Antwort: B
micrometer-registry-prometheus registriert ein PrometheusMeterRegistry und serviert bei Exposure Metriken unter /actuator/prometheus zum Scrapen. Allgemeine Metriken bleiben über /actuator/metrics verfügbar.
Warum die anderen Optionen falsch sind:
- A) Web Exposure serviert HTTP Scrape Endpoint, nicht JMX-only.
- C) Health und Prometheus Endpoints sind getrennt.
- D) Boot bietet integrierte Actuator-Unterstützung ohne mandatory custom Controller.
Merksatz: „Prometheus Registry + Exposure → Scrapen unter /actuator/prometheus."
Weiterlernen: Buchkapitel
Frage 29
Ein GET-Request kommt für /api/orders an. Welcher Mapping-Handler wird gewählt?
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@GetMapping("/{id}")
public OrderDto get(@PathVariable Long id) { return service.find(id); }
@GetMapping("")
public List<OrderDto> list() { return service.findAll(); }
}
- A) get(@PathVariable Long id), weil Path Variables Vorrang haben
- B) list(), weil das leere Pfadsegment den Collection-Endpoint matcht
- C) Beide matchen und Spring liefert 500 Ambiguous mapping
- D) Keiner; /api/orders erfordert nur Trailing-Slash-Mapping
Antwort & Erklärung
Richtige Antwort: B
GET /api/orders matcht @GetMapping("") auf dem Controller mit class-level /api/orders — löst zu list(). GET /api/orders/42 matcht @GetMapping("/{id}"). Spring MVC unterscheidet explizite Pfadmuster; die Collection-URI ohne id-Segment mappt auf den leeren Sub-Pfad.
Warum die anderen Optionen falsch sind:
- A) /{id} erfordert ein zusätzliches Pfadsegment; bloßes /api/orders liefert es nicht.
- C) Die Muster sind für diese beiden Pfade nicht mehrdeutig.
- D) Trailing-Slash-Verhalten ist konfigurierbar; das Mapping ist ohne Extra-Slash-Regeln gültig.
Merksatz: „/api/orders mappt auf ""-Sub-Pfad; /api/orders/{id} auf Item-Endpoint."
Weiterlernen: Buchkapitel
Frage 30
Ein Client sendet POST /api/users mit Content-Type: application/json und einem fehlerhaften Body.
Welcher Exception-Typ wird typischerweise verarbeitet, bevor eine @ControllerAdvice-Methode für Business-Fehler erreicht wird?
- A) Nur AccessDeniedException von Spring Security
- B) HttpMessageNotReadableException während @RequestBody-Deserialisierung
- C) TransactionSystemException von JPA
- D) BeanCurrentlyInCreationException
Antwort & Erklärung
Richtige Antwort: B
Fehlerhaftes JSON oder Typ-Mismatches beim HttpMessageConverter-Reading triggern HttpMessageNotReadableException in der MVC-Schicht, bevor Controller-Logik läuft. @ControllerAdvice kann sie auf 400 Bad Request mappen.
Warum die anderen Optionen falsch sind:
- A) AccessDeniedException betrifft Authorization-Fehler, nicht JSON-Parsing.
- C) TransactionSystemException tritt in der transactional Persistence-Schicht auf.
- D) BeanCurrentlyInCreationException ist ein Context-Initialisierungsproblem.
Merksatz: „Schlechtes JSON bei @RequestBody → HttpMessageNotReadableException → typisch 400."
Weiterlernen: Buchkapitel
Frage 31
Validierung schlägt bei email fehl. Was passiert standardmäßig, wenn kein @ControllerAdvice MethodArgumentNotValidException behandelt?
public record CreateUserRequest(
@NotBlank String email,
@Min(18) int age
) { }
@PostMapping("/users")
public ResponseEntity<Void> create(@Valid @RequestBody CreateUserRequest req) { }
- A) 200 OK mit leerem Body
- B) 500 Internal Server Error
- C) 400 Bad Request mit Default-MVC-Fehlerbehandlung (oder ProblemDetail in Boot-3-Defaults je nach Konfiguration)
- D) Wird still ignoriert; req kommt mit null email an
Antwort & Erklärung
Richtige Antwort: C
@Valid auf @RequestBody triggert Bean Validation. Constraint-Verletzungen werfen MethodArgumentNotValidException. Ohne Custom Handling antwortet Spring MVC/Boot Default Error Handling typischerweise mit 400 und Fehlerdetails.
Warum die anderen Optionen falsch sind:
- A) Validierungsfehler verhindern den normalen Controller-Erfolgspfad.
- B) Default Handling mappt Client-Validierungsfehler auf 4xx, nicht 500.
- D) Ungültige Requests passieren Validierung nicht still.
Merksatz: „@Valid-Fehler bei @RequestBody → MethodArgumentNotValidException → 400-Klasse Response."
Weiterlernen: Buchkapitel
Frage 32
Welche Komponente ist verantwortlich für die Auswahl der korrekten @RequestMapping-Handler-Methode basierend auf URL, HTTP-Methode und Content-Type?
- A) Ausschließlich HandlerAdapter
- B) ViewResolver
- C) HandlerMapping findet den Handler; HandlerAdapter invokiert ihn
- D) HttpMessageConverter
Antwort & Erklärung
Richtige Antwort: C
DispatcherServlet konsultiert HandlerMapping-Implementierungen, um einen Handler (Controller-Methode) aufzulösen. HandlerAdapter invokiert dann den Handler. ViewResolver löst Views auf; HttpMessageConverter liest/schreibt Bodies.
Warum die anderen Optionen falsch sind:
- A) HandlerAdapter invokiert Handler, führt aber keine Mapping-Auswahl durch.
- B) ViewResolver mappt logische View-Namen auf View-Implementierungen.
- D) HttpMessageConverter behandelt Message Conversion, nicht Handler-Auswahl.
Merksatz: „HandlerMapping findet den Handler; HandlerAdapter führt ihn aus."
Weiterlernen: Buchkapitel
Frage 33
Welcher HttpMessageConverter schreibt wahrscheinlich den Response-Body?
@GetMapping("/report")
public ResponseEntity<byte[]> download() {
byte[] pdf = generator.render();
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=report.pdf")
.contentType(MediaType.APPLICATION_PDF)
.body(pdf);
}
- A) MappingJackson2HttpMessageConverter
- B) StringHttpMessageConverter
- C) ByteArrayHttpMessageConverter oder ResourceHttpMessageConverter je nach Typ
- D) FormHttpMessageConverter
Antwort & Erklärung
Richtige Antwort: C
byte[]-Responses werden von ByteArrayHttpMessageConverter (oder ähnlich) behandelt, wenn Content-Type application/pdf ist. Jackson ist für JSON-Objektgraphen, nicht rohe PDF-Bytes.
Warum die anderen Optionen falsch sind:
- A) Jackson konvertiert Objektgraphen zu JSON, nicht beliebige PDF-Bytes.
- B) String-Converter behandelt String-Bodies, nicht byte arrays mit PDF Content-Type.
- D) Form-Converter behandelt Formulardaten, keine Binary Downloads.
Merksatz: „byte[] + MediaType → ByteArrayHttpMessageConverter, nicht Jackson."
Weiterlernen: Buchkapitel
Frage 34
Eine Controller-Methode liefert ResponseEntity<ProblemDetail> mit Status 404 aus einem @RestControllerAdvice.
Was trifft auf @RestControllerAdvice im Vergleich zu @ControllerAdvice zu?
- A) @RestControllerAdvice funktioniert nur auf @Controller-Klassen, nicht @RestController
- B) @RestControllerAdvice deaktiviert @ExceptionHandler vollständig
- C) @RestControllerAdvice wendet @ResponseBody-Semantik auf @ExceptionHandler-Methoden an und serialisiert Rückgabewerte direkt
- D) @ControllerAdvice kann keine REST-Exceptions behandeln
Antwort & Erklärung
Richtige Antwort: C
@RestControllerAdvice ist eine zusammengesetzte Annotation, die @ResponseBody-Verhalten auf Exception-Handler-Methoden legt — Rückgabewerte werden über HttpMessageConverters geschrieben, ideal für REST-Fehlerpayloads wie ProblemDetail.
Warum die anderen Optionen falsch sind:
- A) Es zielt auf REST-Style Exception Handling über Controller inklusive @RestController.
- B) Es spezialisiert @ExceptionHandler für direkte Message Conversion.
- D) @ControllerAdvice kann Exceptions behandeln; @RestControllerAdvice fügt Response-Body-Semantik hinzu.
Merksatz: „@RestControllerAdvice = @ControllerAdvice + @ResponseBody auf Handlern."
Weiterlernen: Buchkapitel
Frage 35
Client sendet PUT /items/5 mit JSON-Body, wo id-Feld 9 ist. Was ist typisch für id in service.update?
@PutMapping("/items/{id}")
public ItemDto update(@PathVariable Long id, @RequestBody ItemDto dto) {
return service.update(id, dto);
}
- A) Immer 9 aus dem Body; Path Variable wird ignoriert
- B) 400-Fehler automatisch, weil Path- und Body-IDs differieren
- C) Path Variable 5 wird als Methodenparameter id übergeben; Body-Feld id kann abweichen, sofern nicht manuell synchronisiert
- D) Spring merged sie zu 14
Antwort & Erklärung
Richtige Antwort: C
Path Variables und Request-Body-Felder binden unabhängig. @PathVariable Long id kommt aus der URL (/items/5 → 5). Das Body-id-Feld befüllt dto.id separat. Business-Logik muss Mismatches ggf. auflösen.
Warum die anderen Optionen falsch sind:
- A) Path-Variable-Parameter-Binding ist unabhängig von Body-Feldern.
- B) Kein automatischer Fehler, außer Validierung oder Custom Checks erzwingen Gleichheit.
- D) Spring merged IDs nicht arithmetisch.
Merksatz: „@PathVariable und @RequestBody-Felder binden getrennt — in Code abgleichen."
Weiterlernen: Buchkapitel
Frage 36
@CrossOrigin(origins = "https://app.example.com") auf einer Controller-Methode. Wie wendet Spring MVC es an?
- A) Es ersetzt Spring Security CSRF-Konfiguration vollständig
- B) Es betrifft nur @RequestBody JSON-Parsing
- C) Es konfiguriert CORS-Response-Header für diesen Handler via CorsInterceptor/CorsFilter in der MVC-Chain
- D) Es wird ignoriert, außer @EnableWebMvc manuell ohne Boot-Defaults deklariert ist
Antwort & Erklärung
Richtige Antwort: C
@CrossOrigin registriert CORS-Konfiguration für den Handler. DispatcherServlet/CORS-Processing fügt passende Access-Control-*-Header für Preflight und echte Requests mit deklarierten Origins und Methoden hinzu.
Warum die anderen Optionen falsch sind:
- A) CORS und CSRF sind verwandt, aber getrennt; @CrossOrigin ersetzt CSRF-Config nicht.
- B) CORS betrifft Browser Cross-Origin HTTP Policy, nicht Message-Converter-Auswahl.
- D) Spring Boot MVC Auto-Config unterstützt @CrossOrigin ohne manuelles @EnableWebMvc.
Merksatz: „@CrossOrigin fügt CORS-Header für passende Handler in der MVC-Chain hinzu."
Weiterlernen: Buchkapitel
Frage 37
transfer wird außerhalb einer bestehenden Transaktion aufgerufen. amount ist negativ, nachdem debit ausgeführt wurde. Was passiert mit dem debit?
@Service
public class TransferService {
@Transactional
public void transfer(Long from, Long to, BigDecimal amount) {
accountRepo.debit(from, amount);
if (amount.signum() < 0) throw new IllegalArgumentException("negative");
accountRepo.credit(to, amount);
}
}
- A) Debit committet, weil IllegalArgumentException unchecked ist und nie rollbackt
- B) Debit bleibt, weil Rollback nur @Transactional(rollbackFor = Exception.class) erfordert
- C) Default @Transactional rollbackt bei RuntimeException; debit wird zurückgerollt
- D) JPA kompensiert automatisch mit einem credit
Antwort & Erklärung
Richtige Antwort: C
Default @Transactional rollbackt bei RuntimeException und Error. IllegalArgumentException triggert Rollback und macht debit innerhalb derselben Transaktionsgrenze rückgängig. Checked Exceptions rollbacken standardmäßig nicht.
Warum die anderen Optionen falsch sind:
- A) Unchecked Exceptions rollbacken standardmäßig — Gegenteil dieser Behauptung.
- B) rollbackFor erweitert Rollback; Default deckt RuntimeException bereits ab.
- D) Keine automatische Kompensation; Transaction Rollback sichert Konsistenz.
Merksatz: „Default @Transactional rollbackt bei RuntimeException und Error."
Weiterlernen: Buchkapitel
Frage 38
Ein Repository deklariert Optional<Customer> findByEmail(String email);. Spring Data JPA leitet die Query aus dem Methodennamen ab. Welche SQL-Form wird generiert?
- A) SELECT c FROM Customer c WHERE c.email = :email mit erzwungenem limit 2
- B) Native DELETE, weil Optional Mutation impliziert
- C) Query selektiert Customer where email equals Parameter; Optional-Rückgabetyp ändert die WHERE-Klausel nicht
- D) JOIN FETCH aller Collections automatisch
Antwort & Erklärung
Richtige Antwort: C
Abgeleitete Query-Methoden übersetzen findByEmail in eine Query, die auf die email-Property filtert. Optional ist ein Java-Rückgabetyp-Wrapper vom Persistence Provider; er ändert Query-Semantik nicht, erwartet nur null oder eine Zeile.
Warum die anderen Optionen falsch sind:
- A) Kein automatisches limit 2; Eindeutigkeitsverletzungen können NonUniqueResultException werfen.
- B) findBy-Präfix bedeutet Read Query, nicht delete.
- D) JOIN FETCH erfordert explizite Fetch-Join-Syntax im Methodennamen oder @Query.
Merksatz: „findByEmail → WHERE email = ?; Optional wrappt null/ein Ergebnis."
Weiterlernen: Buchkapitel
Frage 39
orderRepo.save(newOrder) wird aufgerufen, wobei newOrder transiente LineItem-Children mit setOrder(this) hat. Was wird persistiert?
@Entity
public class Order {
@OneToMany(mappedBy = "order", cascade = CascadeType.PERSIST)
private List<LineItem> items = new ArrayList<>();
}
@Entity
public class LineItem {
@ManyToOne
private Order order;
}
- A) Nur Order; LineItem erfordert explizites itemRepo.save jeweils
- B) Nichts bis flush; cascade funktioniert nie bei @OneToMany
- C) Order und LineItems, weil cascade PERSIST zu verknüpften Children über mappedBy-Seite propagiert
- D) Nur LineItems
Antwort & Erklärung
Richtige Antwort: C
CascadeType.PERSIST auf @OneToMany propagiert persist zu verknüpften LineItem-Entities, wenn Order persistiert wird — vorausgesetzt bidirektionale Assoziationen sind gesetzt (lineItem.setOrder(order)). mappedBy zeigt Order als inverse Seite, Cascade fließt aber von Parent-Operationen bei persist des Parents.
Warum die anderen Optionen falsch sind:
- A) Cascade PERSIST macht separate Child-Saves überflüssig.
- B) Cascade funktioniert bei @OneToMany, wenn konfiguriert; Flush-Timing negiert Cascade nicht.
- D) Parent save treibt Cascade zu Children, nicht umgekehrt.
Merksatz: „Cascade PERSIST bei @OneToMany speichert Children, wenn Parent persistiert wird."
Weiterlernen: Buchkapitel
Frage 40
Ein Entity Graph verursacht N+1 Queries beim Laden von Order mit LineItems in einem REST-Endpoint.
Welcher JPA-Ansatz zielt direkt auf Fetch-Strategie für diesen Read-Use-Case?
- A) Generation Strategy nur auf IDENTITY ändern
- B) Order @Transactional markieren
- C) @EntityGraph auf Repository Query oder JOIN FETCH in @Query, um Assoziationen in einem Round Trip zu laden
- D) Von JPA zu JDBC Template wechseln ohne Fetch-Plan-Änderung
Antwort & Erklärung
Richtige Antwort: C
N+1 entsteht, wenn lazy Assoziationen pro Zeile zugegriffen werden. @EntityGraph oder JOIN FETCH lädt definierte Assoziationen eager in der initialen Query — weniger Round Trips. Identity Generation und @Transactional auf Entity fixen Fetch Graphs nicht.
Warum die anderen Optionen falsch sind:
- A) ID-Generierungsstrategie ist unabhängig von Fetch N+1.
- B) @Transactional auf Entity ist ungültig/sinnlos für Fetch-Tuning.
- D) JDBC kann helfen, aber der JPA-native Fix ist Entity Graph oder Fetch Join.
Merksatz: „N+1-Fix: @EntityGraph oder JOIN FETCH der benötigten Assoziationen."
Weiterlernen: Buchkapitel
Frage 41
Welche Optimierungen kann readOnly = true auf unterstützten JPA-Providern ermöglichen?
@Transactional(readOnly = true)
public List<ReportRow> buildReport() {
return repo.heavyAggregationQuery();
}
- A) Garantierter Distributed-Cache-Hit
- B) Automatischer Wechsel zu serializable Transaction Isolation
- C) Hibernate kann Dirty Checking überspringen und den Persistence Context read-optimiert behandeln
- D) Deaktiviert SQL-Ausführung vollständig
Antwort & Erklärung
Richtige Antwort: C
readOnly=true signalisiert, dass keine Zustandsmutation stattfindet. Hibernate kann optimieren, indem Flush/Dirty-Checking-Overhead vermieden wird und mit manchen DataSources JDBC read-only markiert wird. Es deaktiviert SQL nicht und garantiert kein Caching.
Warum die anderen Optionen falsch sind:
- A) Kein garantiertes Cache-Verhalten allein durch readOnly.
- B) Isolation Level ist separate Konfiguration.
- D) Read Queries führen weiterhin SQL aus.
Merksatz: „readOnly=true signalisiert keine Writes — Provider kann Dirty Checking überspringen."
Weiterlernen: Buchkapitel
Frage 42
Spring Data JPA @Modifying @Query("delete from Stock s where s.warehouse = ?1") int clearWarehouse(String w); muss mit welcher transaktionalen Überlegung genutzt werden?
- A) Keine Transaktion für Delete Queries nötig
- B) Funktioniert nur innerhalb @Transactional(readOnly = true)
- C) Typischerweise @Transactional auf aufrufender Service- oder Repository-Methode; evtl. clearAutomatically / flushAutomatically für Konsistenz
- D) @Modifying Queries können nicht mit abgeleiteten Delete-Methoden genutzt werden
Antwort & Erklärung
Richtige Antwort: C
@Modifying Queries führen DML aus und erfordern eine aktive Transaktion. Entwickler fügen oft @Transactional auf der Service-Schicht hinzu und konfigurieren clearAutomatically, um den Persistence Context nach Bulk-Operationen zu refreshen.
Warum die anderen Optionen falsch sind:
- A) DML ohne Transaktion schlägt fehl oder verhält sich inkonsistent je nach Provider.
- B) readOnly-Transaktionen verbieten Writes.
- D) @Modifying gilt für @Query DML; abgeleitete Delete-Methoden existieren separat.
Merksatz: „@Modifying DML braucht Write-Transaktion und oft clearAutomatically."
Weiterlernen: Buchkapitel
Frage 43
Zwei Transaktionen lesen dasselbe Product version=3. Beide ändern price und speichern. Was ist erwartbar?
@Entity
public class Product {
@Version
private Long version;
}
- A) Last commit wins immer still
- B) Database Deadlocks sind garantiert
- C) Zweiter Commit wirft wahrscheinlich OptimisticLockException, weil @Version beim ersten erfolgreichen Update inkrementiert
- D) @Version blockiert alle concurrent reads
Antwort & Erklärung
Richtige Antwort: C
JPA Optimistic Locking nutzt @Version. Erste Transaktion erfolgreich und inkrementiert Version. Zweites Update nutzt stale Version in WHERE-Klausel, betrifft null Zeilen → OptimisticLockException beim Flush/Commit.
Warum die anderen Optionen falsch sind:
- A) Optimistic Locking erkennt Lost Updates; kein stilles Last-Writer-Wins.
- B) Deadlock ist nicht garantiert; das ist optimistic conflict detection.
- D) Reads laufen weiter; Konflikt erscheint bei widersprüchlichen Writes.
Merksatz: „Stale @Version beim Update → OptimisticLockException, kein stilles Überschreiben."
Weiterlernen: Buchkapitel
Frage 44
Eine @Transactional Service-Methode ruft eine andere @Transactional-Methode in derselben Klasse via this.internal() auf.
Warum könnte @Transactional auf internal() ignoriert werden?
- A) Transaktionen funktionieren nie auf privaten Methoden; public internal() joined immer
- B) Beide Methoden laufen immer in separaten Transaktionen
- C) Spring-AOP-Proxies fangen Self-Invocation über this nicht ab; nur externe Aufrufe über den Proxy wenden Transaction Advice an
- D) Spring Boot deaktiviert deklarative Transaktionen
Antwort & Erklärung
Richtige Antwort: C
Transaction Management nutzt Proxies. this.internal() umgeht den Proxy — @Transactional auf internal() startet evtl. keine neue Transaktion oder joined nicht wie erwartet. Externe Aufrufe über injizierten Self-Proxy oder Refactoring beheben das.
Warum die anderen Optionen falsch sind:
- A) Public Self-Invocation umgeht weiterhin Proxy; Sichtbarkeit ist nicht der alleinige Faktor.
- B) Ohne Proxy-Interception läuft internal() evtl. ohne Transactional Advice.
- D) Boot aktiviert @EnableTransactionManagement via Auto-Config.
Merksatz: „this.internal() umgeht transactional Proxy — Self-Invocation-Falle."
Weiterlernen: Buchkapitel
Frage 45
In Spring Security 6 Lambda DSL: Was bedeutet anyRequest().authenticated() für GET /admin?
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(withDefaults());
- A) Anonym erlaubt, weil formLogin alle GET-Requests aktiviert
- B) Erfordert implizit ROLE_ADMIN
- C) Erfordert einen authentifizierten Principal; unauthentifizierte Nutzer werden für Browser-Requests zum Login umgeleitet
- D) CSRF-Token befreit /admin von Authentication
Antwort & Erklärung
Richtige Antwort: C
anyRequest().authenticated() verlangt Authentication für Requests, die nicht von vorherigen permitAll-Regeln gematcht werden. formLogin konfiguriert einen Login-Flow; Browser-Clients erhalten typischerweise Redirect zu /login, APIs evtl. 401 je nach Entry-Point-Konfiguration.
Warum die anderen Optionen falsch sind:
- A) formLogin umgeht Authentication für geschützte Pfade nicht.
- B) authenticated() ist nicht rollenspezifisch; ROLE_ADMIN bräuchte hasRole("ADMIN").
- D) CSRF ist getrennt von Authentication-Anforderungen.
Merksatz: „anyRequest().authenticated() = eingeloggt sein müssen; nicht rollenspezifisch."
Weiterlernen: Buchkapitel
Frage 46
Ein BCryptPasswordEncoder-Bean verifiziert Login. Wo sollten Raw-Passwörter mit gespeicherten Hashes verglichen werden?
- A) Direkter String-equals im Controller
- B) Nur automatisch in JWT-Signatur-Validierung
- C) Im JPA-Entity-Setter für password
- D) AuthenticationProvider oder UserDetailsService-Flow, der PasswordEncoder.matches(raw, encoded) delegiert
Antwort & Erklärung
Richtige Antwort: D
Spring Security Authentication nutzt PasswordEncoder.matches zum Vergleich präsentierter Credentials mit gespeicherten encoded Passwords. Controller und Entity Setter dürfen keine manuelle Passwort-Verifikationslogik enthalten.
Warum die anderen Optionen falsch sind:
- A) Controller sollten Credential-Vergleich nicht handhaben.
- B) JWT-Validierung prüft Token-Integrität, nicht direkt bcrypt Login-Vergleich.
- C) Entities sollten keine Authentication-Logik besitzen.
Merksatz: „Login: raw vs hash mit PasswordEncoder.matches im Auth-Flow vergleichen."
Weiterlernen: Buchkapitel
Frage 47
Welche Fähigkeit bietet SpEL in diesem @PreAuthorize-Ausdruck?
@PreAuthorize("hasRole('MANAGER') and #invoice.customerId == authentication.principal.customerId")
public InvoiceDto getInvoice(Invoice invoice) { }
- A) Nur Compile-Time-Enforcement ohne Runtime-Checks
- B) Automatischer Database Row Lock
- C) Ersatz von Method Security durch nur URL-basiertes authorizeHttpRequests
- D) Zugriff auf Methodenargumente (#invoice) und Authentication Principal für feingranulare Authorization
Antwort & Erklärung
Richtige Antwort: D
Method Security SpEL kann Methodenparameter mit #name und Authentication-Details referenzieren. Das ermöglicht datenzentrierte Authorization über statische Rollen auf URL-Ebene hinaus.
Warum die anderen Optionen falsch sind:
- A) @PreAuthorize wird zur Laufzeit vor Methodenausführung evaluiert.
- B) Authorization-Ausdruck impliziert kein Locking.
- C) Method Security ergänzt URL Security; ersetzt sie nicht.
Merksatz: „@PreAuthorize SpEL kann #params und authentication.principal nutzen."
Weiterlernen: Buchkapitel
Frage 48
Eine stateless REST API nutzt JWT Bearer Tokens. SessionCreationPolicy ist STATELESS.
Was trifft auf HttpSession-Nutzung zu?
- A) Spring Security erzeugt weiter Sessions für CSRF Tokens immer
- B) STATELESS deaktiviert Authentication vollständig
- C) JWT erfordert server HTTP Session zum Token-Speichern
- D) Keine Server-Session für Authentication State; jeder Request wird via Bearer-Token-Filter-Chain authentifiziert
Antwort & Erklärung
Richtige Antwort: D
STATELESS-Policy verhindert, dass Spring Security HttpSession für Security-Context-Persistenz erzeugt oder nutzt. JWT-Requests authentifizieren pro Request über die Filter Chain ohne serverseitigen Session State.
Warum die anderen Optionen falsch sind:
- A) Stateless APIs deaktivieren typischerweise CSRF für Bearer; Sessions werden nicht für Auth erzeugt.
- B) STATELESS entfernt Session-Speicherung, nicht Authentication.
- C) Bearer Tokens reisen im Authorization-Header; Server muss sie nicht in Session speichern.
Merksatz: „STATELESS = keine Security HttpSession; JWT Auth pro Request."
Weiterlernen: Buchkapitel
Frage 49
CORS Preflight OPTIONS Request trifft /api/data. Spring Security ist mit cors(withDefaults()) konfiguriert. Wer antwortet auf OPTIONS?
- A) Nur Browser; Server sieht OPTIONS nie
- B) OPTIONS erfordert immer ADMIN-Rolle
- C) DispatcherServlet lehnt OPTIONS ab, außer @CrossOrigin fehlt
- D) CORS Filter/Integration darf OPTIONS vor Authentication autorisieren und fügt CORS Header per Konfiguration hinzu
Antwort & Erklärung
Richtige Antwort: D
CORS Integration behandelt Preflight OPTIONS Requests, erlaubt sie oft ohne Authentication und liefert erlaubte Origins/Methods/Headers. Echte Data Requests erfordern weiter normale Auth-Regeln.
Warum die anderen Optionen falsch sind:
- A) Preflight OPTIONS wird an den Server gesendet.
- B) Preflight ist typischerweise nicht ADMIN-gated.
- C) @CrossOrigin und globale CORS Config ermöglichen Handling; OPTIONS wird nicht blind abgelehnt.
Merksatz: „CORS Preflight OPTIONS oft separat erlaubt von authentifiziertem GET/POST."
Weiterlernen: Buchkapitel
Frage 50
@WithMockUser(roles = "ADMIN") wird auf einem @WebMvcTest-Slice für AdminController genutzt.
Was liefert diese Annotation?
- A) Einen vollen Integrationstest gegen echte Database User Table
- B) Automatisches JWT Token Minting gegen OAuth Server
- C) Deaktiviert Spring Security für den Test
- D) Einen SecurityContext mit mock authentifiziertem User für den Test-Request, ohne UserDetailsService
Antwort & Erklärung
Richtige Antwort: D
@WithMockUser befüllt den SecurityContext mit synthetischem Principal und Granted Authorities für Slice/Full-MVC-Tests — Authorization Checks ohne echte User zu laden.
Warum die anderen Optionen falsch sind:
- A) Es ist ein Test-Shortcut, keine database-backed Authentication.
- B) Kein OAuth/JWT Issuance.
- C) Security bleibt aktiv mit gemocktem User.
Merksatz: „@WithMockUser fälscht SecurityContext Principal für MVC-Tests."
Weiterlernen: Buchkapitel
Frage 51
Welche Beans werden im Test ApplicationContext geladen?
@WebMvcTest(controllers = InvoiceController.class)
class InvoiceControllerTest {
@Autowired MockMvc mockMvc;
@MockBean InvoiceService invoiceService;
}
- A) Vollständige Anwendung inklusive JPA Repositories und DataSource
- B) Nur InvoiceController ohne MockMvc
- C) Gesamte Spring Security Filter Chain aus main immer ohne Konfiguration
- D) Web-Layer-Slice: MVC-Infrastruktur, InvoiceController und gemockter InvoiceService-Ersatz
Antwort & Erklärung
Richtige Antwort: D
@WebMvcTest lädt einen begrenzten MVC-fokussierten Context für den angegebenen Controller, auto-konfiguriert MockMvc und Spring Security wenn auf Classpath. @MockBean ersetzt InvoiceService im Context zur Isolation.
Warum die anderen Optionen falsch sind:
- A) Full @SpringBootTest lädt alles; @WebMvcTest ist ein Slice.
- B) MockMvc ist in @WebMvcTest auto-konfiguriert.
- C) Security Test Support ist partiell, sofern nicht importiert; nicht garantiert volle main Chain.
Merksatz: „@WebMvcTest = Controller-Slice + MockMvc + @MockBean Collaborators."
Weiterlernen: Buchkapitel
Frage 52
@DataJpaTest lädt standardmäßig eine In-Memory-Datenbank. Welche Aussage ist korrekt?
- A) Startet die volle Web-Umgebung auf einem Random Port
- B) Ersetzt @Entity-Klassen durch Mocks
- C) Erfordert @SpringBootTest auf derselben Klasse
- D) Konfiguriert JPA-Test-Infrastruktur, Repositories unter Test und rollt Transaktionen nach jeder Testmethode standardmäßig zurück
Antwort & Erklärung
Richtige Antwort: D
@DataJpaTest ist ein JPA-Slice, der Auto-Configuration für TestEntityManager, In-Memory-DataSource (typischerweise) und @Transactional Rollback pro Testmethode importiert, sofern nicht @Commit genutzt wird.
Warum die anderen Optionen falsch sind:
- A) Web-Umgebung startet nicht in @DataJpaTest.
- B) Echtes @Entity Mapping wird getestet, keine gemockten Entities.
- C) @DataJpaTest ist eigenständig; @SpringBootTest ist nicht erforderlich.
Merksatz: „@DataJpaTest = JPA-Slice, In-Memory-DB, transactional Rollback pro Test."
Weiterlernen: Buchkapitel
Frage 53
Dies ist ein fokussierter Unit/Integration-Hybrid ohne @SpringBootTest. Was ist wahr?
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {OrderService.class, TestConfig.class})
class OrderServiceTest {
@Autowired OrderService orderService;
@MockBean PaymentGateway gateway;
}
- A) @MockBean erfordert immer @SpringBootTest
- B) @ContextConfiguration kann keine @Service-Klassen laden
- C) PaymentGateway Mock wird nur injiziert, wenn @InjectMocks vorhanden ist
- D) SpringExtension baut Context aus angegebenen Klassen; @MockBean fügt Mockito Mocks als Beans hinzu
Antwort & Erklärung
Richtige Antwort: D
Spring TestContext Framework kann minimale Configurations via @ContextConfiguration laden. @MockBean (oder @MockitoBean in neueren Versionen) registriert Mocks im Context, sodass @Autowired Services sie erhalten.
Warum die anderen Optionen falsch sind:
- A) @MockBean funktioniert in sliced/custom Contexts mit SpringExtension.
- B) @Service-Klassen sind gültige Context-Configuration-Einträge.
- C) @InjectMocks ist reines Mockito; hier injiziert Spring den @MockBean in OrderService.
Merksatz: „@ContextConfiguration + @MockBean baut minimale Spring-Test-Contexts."
Weiterlernen: Buchkapitel
Frage 54
@SpringBootTest(webEnvironment = RANDOM_PORT) mit TestRestTemplate ruft Actuator /health auf.
Was impliziert RANDOM_PORT?
- A) Kein Servlet Container startet; TestRestTemplate ist inert
- B) Nur MockMvc kann genutzt werden
- C) Port 8080 ist hard-coded
- D) Embedded Server startet auf Random verfügbarem Port; Tests nutzen echtes HTTP gegen localhost
Antwort & Erklärung
Richtige Antwort: D
RANDOM_PORT startet den vollen embedded Web Server auf ephemeral Port. TestRestTemplate oder WebTestClient können echte HTTP Requests senden — geeignet für Integrationstests inklusive Actuator Endpoints.
Warum die anderen Optionen falsch sind:
- A) Servlet Container startet in Web Environments.
- B) MockMvc ist für in-process MVC; RANDOM_PORT ermöglicht echte HTTP Clients.
- C) Port ist random, nicht fix 8080.
Merksatz: „RANDOM_PORT = echter embedded Server auf ephemeral Port für HTTP-Tests."
Weiterlernen: Buchkapitel
Frage 55
@TestConfiguration innerhalb einer Testklasse definiert extra Beans. Wie unterscheidet sie sich von main @Configuration?
- A) Ersetzt application.properties permanent
- B) Läuft immer vor main Sources in Production
- C) Kann keine @Bean-Methoden definieren
- D) Wird in Production nicht per Component Scanning gefunden und explizit für Tests importiert
Antwort & Erklärung
Richtige Antwort: D
@TestConfiguration ist spezialisiertes @Configuration, das in Production nicht auto-gescannt wird. Tests importieren es via @Import, @SpringBootTest classes-Attribut oder nested static class patterns zum Override oder Hinzufügen von Beans.
Warum die anderen Optionen falsch sind:
- A) Es mutiert keine Production Property Files.
- B) Es ist test-scoped, kein Production Startup.
- C) @Bean-Methoden werden üblicherweise in Test Configuration definiert.
Merksatz: „@TestConfiguration = nur Test-Beans, nicht production-scanned."
Weiterlernen: Buchkapitel
Frage 56
Welche Libraries sind idiomatisch für diese Assertions in Spring Service Tests?
verify(gateway, times(1)).charge(any());
assertThat(result.getStatus()).isEqualTo(OrderStatus.PAID);
- A) Nur JUnit 4 Hamcrest
- B) Nur Spring MVC Test
- C) JdbcTemplate queryForObject
- D) Mockito verify für Interaktionen und AssertJ assertThat für fluent Assertions
Antwort & Erklärung
Richtige Antwort: D
Moderne Spring Tests kombinieren Mockito (verify, when) für Collaborator-Verhalten mit AssertJ fluent Assertions für lesbare State Checks. JUnit 5 ist Baseline Test Engine in Boot 3.
Warum die anderen Optionen falsch sind:
- A) JUnit 5 mit AssertJ ist moderner Default, nicht nur JUnit 4.
- B) MVC Test zielt auf Controller, nicht Service Mockito verify Patterns.
- C) JdbcTemplate ist unabhängig von diesen Assertion APIs.
Merksatz: „Service Tests: Mockito verify + AssertJ assertThat auf JUnit 5."
Weiterlernen: Buchkapitel
Frage 57
@Transactional ist auf charge() angewendet. Externer Client ruft chargeWrapper() über den Spring Proxy auf. Was passiert?
@Service
public class BillingService {
@Transactional
public void charge() { ledger.post(); }
public void chargeWrapper() { charge(); }
}
- A) Transaktion startet, weil charge() @Transactional ist, unabhängig vom Entry Method
- B) chargeWrapper erbt automatisch @Transactional vom Callee
- C) CGLIB merged beide Methoden immer in eine transactional Boundary
- D) Transaction Advice greift evtl. nicht: interner Aufruf von chargeWrapper() zu charge() umgeht Proxy
Antwort & Erklärung
Richtige Antwort: D
Gleiche Self-Invocation-Limitation wie transactional AOP: chargeWrapper() ruft this.charge() intern auf und passiert nicht durch den Proxy — @Transactional auf charge() aktiviert evtl. nicht, wenn über chargeWrapper() eingetreten.
Warum die anderen Optionen falsch sind:
- A) Proxy gilt für externe Aufrufe über Proxy Bean, nicht interne this-Aufrufe.
- B) Annotationen werden nicht automatisch über Methoden vererbt.
- C) CGLIB wrappt interne Methodenaufrufe nicht retroaktiv.
Merksatz: „Internes this.charge() aus non-advised Methode überspringt @Transactional Proxy."
Weiterlernen: Buchkapitel
Frage 58
Was ist nötig, damit dieser Listener asynchron auf separatem Thread läuft?
@EventListener
@Async
public void handle(OrderPlacedEvent event) { email.send(event); }
- A) Nur @EventListener reicht; async ist Default
- B) @Transactional auf der Listener-Methode
- C) ApplicationEventPublisher durch JMS ersetzen
- D) @EnableAsync und Executor Bean oder Spring Boot auto-konfigurierter Task Executor
Antwort & Erklärung
Richtige Antwort: D
@Async-Methoden laufen über Spring Task Execution Infrastructure, aktiviert durch @EnableAsync (Boot auto-konfiguriert wenn vorhanden). Ohne aktivierte Async Execution läuft @Async synchron oder schlägt je nach Konfiguration fehl.
Warum die anderen Optionen falsch sind:
- A) Event Listener sind synchron, sofern @Async Infrastructure nicht aktiviert ist.
- B) @Transactional liefert kein async Thread Dispatch.
- C) In-process async Events brauchen kein JMS.
Merksatz: „@Async Listener brauchen @EnableAsync und TaskExecutor."
Weiterlernen: Buchkapitel
Frage 59
ApplicationEventPublisher publiziert ein custom OrderCancelledEvent; Commit der Transaktion ist gewünscht. Welche Annotation stellt sicher, dass Listener committed Data sehen?
- A) @EventListener allein wartet immer auf Commit
- B) Nur @Async
- C) @Order(0)
- D) @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
Antwort & Erklärung
Richtige Antwort: D
@TransactionalEventListener mit AFTER_COMMIT plant Event Handling nur, wenn die Transaktion erfolgreich committet — Listener lesen keinen uncommitted State.
Warum die anderen Optionen falsch sind:
- A) Plain @EventListener feuert sofort, nicht necessarily nach Commit.
- B) @Async betrifft Thread, nicht Transaction Phase Alignment.
- C) @Order steuert Listener-Reihenfolge, nicht Transaction Commit Phase.
Merksatz: „AFTER_COMMIT transactional Listener läuft nur bei erfolgreichem TX."
Weiterlernen: Buchkapitel
Frage 60
Micrometer Timer Metric order.latency ist registriert. management.tracing.enabled=true mit OpenTelemetry Bridge.
Welches Ergebnis ist in einem Boot-3-Observability-Setup am zutreffendsten?
- A) Metriken und Traces schließen sich gegenseitig aus; Tracing deaktiviert Timer
- B) Actuator /health enthält automatisch volle distributed Trace Trees
- C) Observability erfordert Ersatz von Logback durch Log4j1
- D) Order Handler kann Timer Metrics aufzeichnen, während HTTP Requests auch Trace Spans via Micrometer Observation oder OTel Bridge propagieren
Antwort & Erklärung
Richtige Antwort: D
Spring Boot 3 integriert Micrometer Observation und verknüpft Metriken, Logging und Tracing. Custom Timer Metrics koexistieren mit Distributed Tracing, wenn Tracing Dependencies und Properties konfiguriert sind.
Warum die anderen Optionen falsch sind:
- A) Metriken und Tracing ergänzen sich via Observation API.
- B) Health Endpoint meldet Health Status, keine vollen Trace Trees.
- C) Log-Implementierung ist unabhängig von Metrics/Tracing Bridge.
Merksatz: „Boot 3 Observation verknüpft Metriken, Logs und Traces — sie koexistieren."
Weiterlernen: Buchkapitel
Ende von Mock Full 06 — Spring Professional (60 Fragen)