Skip to main content

English + German

English stays on the page. Click the button to show the German text under each question.

Spring Core

If you cannot explain IoC without the word “magic”, the rest of Spring will sound like annotations. This page is the baseline for every Spring interview.

Study links sit under each question. The deep chapters are in Week 1 and Week 2.

Deutsch

Spring Core

Wenn du IoC nicht ohne das Wort „Magie“ erklären kannst, klingt der Rest von Spring nach Annotationen. Diese Seite ist die Basis für jedes Spring-Interview.

Unter jeder Frage sitzt ein Leselink. Die tiefen Kapitel sind in Woche 1 und Woche 2.

1. What problem does Spring solve? IoC vs DI?

Deutsch

Welches Problem löst Spring? IoC vs. DI?

Level: Junior · Listen for: who creates objects; DI is the technique

Niveau: Junior · Darauf hören sie: wer Objekte erzeugt; DI ist die Technik

Model answer

Without a container, services new their collaborators. That hard-wires implementations, hides configuration, and makes tests replace internals with mocks only by subclassing or static tricks.

Inversion of Control means the container owns the lifecycle: it creates, wires, and destroys objects. Dependency Injection is the main technique: collaborators are passed in, usually through the constructor.

Spring is an IoC container plus a large set of integrations. It is not “a web framework” first.

Follow-ups

  • Service Locator vs DI?
  • Why is new still fine for true values and no-dependency helpers?

Trap: “IoC is Dependency Injection” as if the words were identical.

Memory sentence: IoC is the idea; DI is how Spring usually implements it.

Study: What problem does Spring solve?

Musterantwort

Ohne Container erzeugen Services ihre Abhängigkeiten selbst mit new. Das verdrahtet Implementierungen fest, versteckt die Konfiguration, und Tests können interne Abhängigkeiten nur per Subclassing oder statischen Tricks durch Mocks ersetzen.

Inversion of Control heißt: Der Container besitzt den Lifecycle — er erzeugt, verdrahtet und zerstört Objekte. Dependency Injection ist die Haupttechnik: Abhängigkeiten kommen von außen, meist über den Konstruktor.

Spring ist ein IoC-Container plus viele Integrationen. Es ist nicht zuerst „ein Web-Framework“.

Nachfragen

  • Service Locator vs. DI?
  • Warum ist new für echte Werte und Hilfsklassen ohne Abhängigkeiten trotzdem okay?

Falle: „IoC ist Dependency Injection“ — als wären die Wörter dasselbe.

Merksatz: IoC ist die Idee; DI ist der Weg, wie Spring sie meist umsetzt.

Lesen: Welches Problem löst Spring?

2. What is a bean? BeanDefinition vs instance?

Deutsch

Was ist ein Bean? BeanDefinition vs. Instanz?

Level: Mid · Listen for: recipe vs object

Niveau: Mid · Darauf hören sie: Rezept vs. Objekt

Model answer

A bean is an object whose lifecycle Spring manages. A BeanDefinition is the recipe: class name, scope, constructor args, lazy flag, factory method.

Spring reads definitions first (from scanning, @Bean methods, XML), then creates instances according to those recipes. You can have a definition that never becomes an instance if it is lazy and never requested.

Follow-ups

  • What is a factory bean (FactoryBean)?
  • Can two definitions produce the same class?

Trap: “a bean is any Java object.”

Memory sentence: The definition is the recipe; the bean is the cooked object.

Study: Beans and bean definitions

Musterantwort

Ein Bean ist ein Objekt, dessen Lifecycle Spring verwaltet. Eine BeanDefinition ist das Rezept: Klassenname, Scope, Konstruktorargumente, Lazy-Flag, Factory-Methode.

Spring liest zuerst die Definitionen (aus Scanning, @Bean-Methoden, XML) und erzeugt danach Instanzen nach diesen Rezepten. Du kannst eine Definition haben, die nie zur Instanz wird — wenn sie lazy ist und nie angefordert wird.

Nachfragen

  • Was ist ein Factory Bean (FactoryBean)?
  • Können zwei Definitionen dieselbe Klasse erzeugen?

Falle: „Ein Bean ist jedes Java-Objekt.“

Merksatz: Die Definition ist das Rezept; der Bean ist das fertige Objekt.

Lesen: Beans und Bean-Definitionen

3. BeanFactory vs ApplicationContext?

Deutsch

BeanFactory vs. ApplicationContext?

Level: Mid · Listen for: context is the real app container

Niveau: Mid · Darauf hören sie: der Context ist der echte App-Container

Model answer

BeanFactory is the basic IoC SPI: get a bean by name or type. ApplicationContext extends that with environment, events, i18n, resource loading, and eager singleton pre-instantiation by default.

In a Spring Boot app you work with an ApplicationContext (often AnnotationConfigServletWebServerApplicationContext). You almost never program to raw BeanFactory unless you are writing framework code.

Follow-ups

  • Why does Boot fail fast at startup instead of on first request?
  • What is a child context? (dispatcher servlet historically)

Trap: “BeanFactory is deprecated.” It is not; it is just lower-level.

Memory sentence: ApplicationContext is the container your app actually runs in.

Study: ApplicationContext and BeanFactory

Musterantwort

BeanFactory ist das grundlegende IoC-SPI: Bean per Name oder Typ holen. ApplicationContext erweitert das um Environment, Events, i18n, Resource Loading und erzeugt Singletons standardmäßig eager schon beim Start.

In einer Spring-Boot-App arbeitest du mit einem ApplicationContext (oft AnnotationConfigServletWebServerApplicationContext). Du programmierst fast nie gegen das nackte BeanFactory, außer du schreibst Framework-Code.

Nachfragen

  • Warum scheitert Boot schon beim Start, nicht erst beim ersten Request?
  • Was ist ein Child Context? (historisch der DispatcherServlet)

Falle: „BeanFactory ist deprecated.“ Ist es nicht — es ist nur eine Ebene tiefer.

Merksatz: ApplicationContext ist der Container, in dem deine App wirklich läuft.

Lesen: ApplicationContext und BeanFactory

4. Why constructor injection over field @Autowired?

Deutsch

Warum Constructor Injection statt Field-@Autowired?

Level: Mid · Listen for: required deps, immutability, tests, reflection

Niveau: Mid · Darauf hören sie: Pflicht-Abhängigkeiten, Immutability, Tests, Reflection

Model answer

Constructor injection makes required collaborators explicit and final. The object cannot exist in a half-wired state. Tests can new Service(mockRepo) without starting Spring.

Field injection hides dependencies, blocks final, needs reflection, and makes unit tests reach for ReflectionTestUtils. Setter injection is for optional collaborators.

Since Spring 4.3, a single constructor does not even need @Autowired.

Follow-ups

  • What if there are two constructors?
  • Circular constructor injection — what happens?

Trap: “field injection is the Spring way.”

Memory sentence: Required collaborators belong in the constructor.

Study: Dependency injection

Musterantwort

Constructor Injection macht Pflicht-Abhängigkeiten explizit und final. Das Objekt kann nicht halb verdrahtet existieren. Tests können new Service(mockRepo) machen, ohne Spring zu starten.

Field Injection versteckt Abhängigkeiten, blockiert final, braucht Reflection, und Unit-Tests greifen dann zu ReflectionTestUtils. Setter Injection ist für optionale Abhängigkeiten.

Seit Spring 4.3 braucht ein einzelner Konstruktor nicht einmal @Autowired.

Nachfragen

  • Was, wenn es zwei Konstruktoren gibt?
  • Zirkuläre Constructor Injection — was passiert?

Falle: „Field Injection ist der Spring-Weg.“

Merksatz: Pflicht-Abhängigkeiten gehören in den Konstruktor.

Lesen: Dependency Injection

5. @Component vs @Bean? @Service vs @Repository?

Deutsch

@Component vs. @Bean? @Service vs. @Repository?

Level: Mid · Listen for: scanning vs factory methods; stereotype extras

Niveau: Mid · Darauf hören sie: Scanning vs. Factory-Methoden; Extra-Verhalten der Stereotypes

Model answer

@Component (and stereotypes) mark your classes for component scanning. @Bean is a factory method on a @Configuration class — use it for third-party types, conditional construction, or when you cannot annotate the class.

@Service is a semantic @Component. @Repository also translates persistence exceptions into Spring’s DataAccessException hierarchy. @Controller / @RestController register handler methods.

Follow-ups

  • Why do @Bean methods on @Configuration get proxied?
  • What if you put @Bean on a non-@Configuration class (@Component lite mode)?

Trap:@Service creates a bean even if the package is not scanned.”

Memory sentence: Scan your code with stereotypes; wrap foreign objects with @Bean.

Study: Component scanning

Musterantwort

@Component (und Stereotypes) markieren deine Klassen für Component Scanning. @Bean ist eine Factory-Methode auf einer @Configuration-Klasse — nutze sie für Third-Party-Typen, bedingte Erzeugung oder wenn du die Klasse nicht annotieren kannst.

@Service ist ein semantisches @Component. @Repository übersetzt außerdem Persistence-Exceptions in Springs DataAccessException-Hierarchie. @Controller / @RestController registrieren Handler-Methoden.

Nachfragen

  • Warum werden @Bean-Methoden auf @Configuration per Proxy behandelt?
  • Was passiert, wenn du @Bean auf eine Klasse ohne @Configuration setzt (@Component Lite Mode)?

Falle:@Service erzeugt einen Bean, auch wenn das Package nicht gescannt wird.“

Merksatz: Scanne deinen Code mit Stereotypes; fremde Objekte holst du über @Bean.

Lesen: Component Scanning

6. What happens if two beans match one injection point?

Deutsch

Was passiert, wenn zwei Beans zu einem Injection Point passen?

Level: Mid · Listen for: NoUniqueBeanDefinitionException; @Primary vs @Qualifier

Niveau: Mid · Darauf hören sie: NoUniqueBeanDefinitionException; @Primary vs. @Qualifier

Model answer

Spring fails at startup (or at first injection for lazy) with ambiguity.

Resolve with:

  • @Primary — the default when no qualifier is given
  • @Qualifier — a specific name/token
  • inject a List<PaymentClient> if you want all
  • make the types more specific

@Resource matches by name first. @Autowired matches by type first. I stay with constructor + @Qualifier for required one-of-many.

Follow-ups

  • @Resource vs @Autowired vs @Inject?
  • What does @ConditionalOnMissingBean have to do with this?

Trap: adding @Primary on everything to silence the error.

Memory sentence: Type match is not enough when two candidates exist — pick primary, qualifier, or a collection.

Study: Dependency injection

Musterantwort

Spring scheitert beim Start (oder bei der ersten Injection, wenn lazy) an der Mehrdeutigkeit.

So löst du es:

  • @Primary — der Default, wenn kein Qualifier gesetzt ist
  • @Qualifier — ein bestimmter Name/Token
  • eine List<PaymentClient> injizieren, wenn du alle willst
  • die Typen spezifischer machen

@Resource matcht zuerst nach Name. @Autowired matcht zuerst nach Typ. Bei einer Pflicht-Abhängigkeit unter mehreren bleibe ich bei Konstruktor + @Qualifier.

Nachfragen

  • @Resource vs. @Autowired vs. @Inject?
  • Was hat @ConditionalOnMissingBean damit zu tun?

Falle: überall @Primary setzen, nur um den Fehler zu unterdrücken.

Merksatz: Typ-Match reicht nicht, wenn zwei Kandidaten da sind — nimm Primary, Qualifier oder eine Collection.

Lesen: Dependency Injection

7. Singleton vs prototype, and the prototype-in-singleton trap?

Deutsch

Singleton vs. Prototype, und die Prototype-in-Singleton-Falle?

Level: Mid · Listen for: one instance per container; lookup for fresh instances

Niveau: Mid · Darauf hören sie: eine Instanz pro Container; Lookup für frische Instanzen

Model answer

Singleton (default): one instance per Spring container, shared across requests. It must be thread-safe.

Prototype: a new instance whenever Spring is asked for that bean. Request/session scopes exist in web apps.

Trap: a singleton injects a prototype once at construction. It then holds that one instance forever. To get a fresh prototype, inject ObjectProvider<T>, ObjectFactory<T>, or use a lookup method.

Follow-ups

  • Scoped proxy (@Scope(proxyMode = TARGET_CLASS))?
  • Is singleton thread-safe by default? (no)

Trap: “prototype means one per HTTP request.” That is request scope.

Memory sentence: A singleton captures an injected prototype at creation time unless you look it up again.

Study: Bean scopes

Musterantwort

Singleton (Default): eine Instanz pro Spring-Container, geteilt über alle Requests. Muss thread-safe sein.

Prototype: eine neue Instanz, sobald Spring nach diesem Bean gefragt wird. Request- und Session-Scopes gibt es in Web-Apps.

Die Falle: ein Singleton injiziert ein Prototype einmal bei der Konstruktion. Danach hält er für immer dieselbe Instanz. Für eine frische Prototype-Instanz injiziere ObjectProvider<T>, ObjectFactory<T> oder nutze eine Lookup-Methode.

Nachfragen

  • Scoped Proxy (@Scope(proxyMode = TARGET_CLASS))?
  • Ist Singleton standardmäßig thread-safe? (nein)

Falle: „Prototype heißt eins pro HTTP-Request.“ Das ist Request Scope.

Merksatz: Ein Singleton hält das injizierte Prototype zum Erzeugungszeitpunkt fest — außer du holst es später per Lookup.

Lesen: Bean Scopes

8. Walk through the bean lifecycle.

Deutsch

Geh den Bean-Lifecycle durch.

Level: Mid · Listen for: instantiate, inject, aware, BeanPostProcessor, init, use, destroy

Niveau: Mid · Darauf hören sie: instanziieren, injizieren, Aware-Callbacks, BeanPostProcessor, Init, Nutzung, Destroy

Model answer

Rough order:

  1. instantiate (constructor)
  2. inject properties / fields
  3. aware callbacks (BeanNameAware, ApplicationContextAware)
  4. BeanPostProcessor.before
  5. @PostConstruct / InitializingBean / custom init
  6. BeanPostProcessor.afterthis is where proxies usually wrap the bean
  7. bean is in use
  8. @PreDestroy / DisposableBean / custom destroy on singleton shutdown

Prototype beans are not fully tracked for destroy. @Transactional and @Async work because a post-processor replaces the bean with a proxy.

Follow-ups

  • @PostConstruct vs constructor for logic that needs injected fields? (constructor is enough with ctor injection)
  • Why can you not call @Transactional methods from the constructor?

Trap: putting business startup in the constructor of a proxied bean.

Memory sentence: Create, inject, init, then proxy; destroy only for managed singletons.

Study: Bean lifecycle

Musterantwort

Ungefähre Reihenfolge:

  1. instanziieren (Konstruktor)
  2. Properties / Felder injizieren
  3. Aware-Callbacks (BeanNameAware, ApplicationContextAware)
  4. BeanPostProcessor.before
  5. @PostConstruct / InitializingBean / eigenes Init
  6. BeanPostProcessor.afterhier wrappen Proxies den Bean meist
  7. Bean ist in Nutzung
  8. @PreDestroy / DisposableBean / eigenes Destroy beim Singleton-Shutdown

Prototype-Beans werden für Destroy nicht vollständig nachverfolgt. @Transactional und @Async funktionieren, weil ein Post-Processor den Bean durch einen Proxy ersetzt.

Nachfragen

  • @PostConstruct vs. Konstruktor für Logik, die injizierte Felder braucht? (bei Constructor Injection reicht der Konstruktor)
  • Warum kannst du @Transactional-Methoden nicht aus dem Konstruktor aufrufen?

Falle: Startlogik in den Konstruktor eines per Proxy gewrappten Beans legen.

Merksatz: Erzeugen, injizieren, Init, dann Proxy; Destroy nur für verwaltete Singletons.

Lesen: Bean Lifecycle

9. Circular dependencies — when do they work and when do they fail?

Deutsch

Zirkuläre Abhängigkeiten — wann funktionieren sie, wann scheitern sie?

Level: Senior · Listen for: constructor cycles fail; setter/field may be patched

Niveau: Senior · Darauf hören sie: Konstruktor-Zyklen scheitern; Setter/Field können geflickt werden

Model answer

A constructor cycle (A needs B, B needs A) fails at startup. Spring cannot instantiate either.

A field/setter cycle may be resolved by injecting a reference before the other bean is fully initialized. Boot 2.6+ disallows circular references by default even then — you should fix the design, not set spring.main.allow-circular-references=true.

Fix: extract a third type, use events, or invert one dependency. A @Lazy injection point is a workaround, not a design.

Follow-ups

  • Why does constructor injection make cycles visible?
  • How does a proxy help @Lazy break a cycle?

Trap: enabling circular references to “make the tests pass”.

Memory sentence: Constructor cycles fail loudly; that is a feature — split the types.

Study: Dependency injection

Musterantwort

Ein Konstruktor-Zyklus (A braucht B, B braucht A) scheitert beim Start. Spring kann keines von beiden instanziieren.

Ein Field-/Setter-Zyklus kann aufgelöst werden, indem eine Referenz injiziert wird, bevor der andere Bean vollständig initialisiert ist. Boot 2.6+ verbietet zirkuläre Referenzen standardmäßig trotzdem — du solltest das Design fixen, nicht spring.main.allow-circular-references=true setzen.

Lösung: einen dritten Typ rausziehen, Events nutzen oder eine Abhängigkeit umdrehen. Ein @Lazy-Injection-Point ist ein Workaround, kein Design.

Nachfragen

  • Warum macht Constructor Injection Zyklen sichtbar?
  • Wie hilft ein Proxy @Lazy, einen Zyklus zu brechen?

Falle: zirkuläre Referenzen einschalten, „damit die Tests grün werden“.

Merksatz: Konstruktor-Zyklen scheitern laut — das ist ein Feature. Typen aufteilen.

Lesen: Dependency Injection

10. @Configuration proxy vs lite mode?

Deutsch

@Configuration-Proxy vs. Lite Mode?

Level: Mid · Listen for: calling @Bean methods from other @Bean methods

Niveau: Mid · Darauf hören sie: @Bean-Methoden, die andere @Bean-Methoden aufrufen

Model answer

A full @Configuration class is subclassed (CGLIB). When one @Bean method calls another, you get the container-managed singleton, not a second new.

If the same methods live on a @Component (@Bean lite mode), a direct call is a plain Java call and creates a second instance. That breaks “one DataSource” assumptions.

@Configuration(proxyBeanMethods = false) is an explicit lite mode used for performance and for Boot auto-config. Then you must inject collaborators as method parameters, not via inter-bean calls.

Follow-ups

  • Why does Boot prefer proxyBeanMethods = false in auto-config?
  • Can @Configuration classes be final? (not if they need the CGLIB subclass)

Trap: calling new Foo() inside a @Bean method and also declaring @Bean Foo elsewhere.

Memory sentence: Full @Configuration intercepts @Bean calls; lite mode does not.

Study: Java configuration

Musterantwort

Eine vollständige @Configuration-Klasse bekommt eine CGLIB-Subclass. Ruft eine @Bean-Methode eine andere auf, bekommst du den vom Container verwalteten Singleton, nicht ein zweites new.

Liegen dieselben Methoden auf einem @Component (@Bean Lite Mode), ist ein direkter Aufruf ein normaler Java-Aufruf und erzeugt eine zweite Instanz. Das bricht die Annahme „eine DataSource“.

@Configuration(proxyBeanMethods = false) ist ein expliziter Lite Mode — für Performance und für Boot Auto-Config. Dann musst du Abhängigkeiten als Methodenparameter injizieren, nicht über Aufrufe zwischen @Bean-Methoden.

Nachfragen

  • Warum bevorzugt Boot in Auto-Config proxyBeanMethods = false?
  • Können @Configuration-Klassen final sein? (nicht, wenn sie die CGLIB-Subclass brauchen)

Falle: new Foo() in einer @Bean-Methode aufrufen und zusätzlich woanders @Bean Foo deklarieren.

Merksatz: Vollständige @Configuration fängt @Bean-Aufrufe ab; Lite Mode nicht.

Lesen: Java-Konfiguration

11. @Value vs @ConfigurationProperties?

Deutsch

@Value vs. @ConfigurationProperties?

Level: Mid · Listen for: one property vs typed, validated groups

Niveau: Mid · Darauf hören sie: eine Property vs. typisierte, validierte Gruppen

Model answer

@Value("${app.timeout}") injects one property, with SpEL. Fine for a single flag. Weak for groups: no type-safe prefix, easy typos, hard to validate as a set.

@ConfigurationProperties(prefix = "app") binds a structured object, works with relaxed names (app.timeout-ms / APP_TIMEOUTMS), and can be @Validated (@NotNull, @Min). That is the Boot-native style.

Do not @Value your way through ten related properties.

Follow-ups

  • Relaxed binding rules?
  • Why enable @EnableConfigurationProperties or @ConfigurationPropertiesScan?

Trap: @Value plus SpEL for lists of YAML maps.

Memory sentence: One flag can be @Value; a settings group should be @ConfigurationProperties.

Study: External configuration

Musterantwort

@Value("${app.timeout}") injiziert eine Property, mit SpEL. Okay für ein einzelnes Flag. Schwach für Gruppen: kein typsicheres Prefix, Tippfehler passieren leicht, als Gruppe schwer zu validieren.

@ConfigurationProperties(prefix = "app") bindet ein strukturiertes Objekt, versteht Relaxed Names (app.timeout-ms / APP_TIMEOUTMS) und kann @Validated sein (@NotNull, @Min). Das ist der native Boot-Stil.

Arbeite dich nicht mit @Value durch zehn zusammengehörige Properties.

Nachfragen

  • Regeln für Relaxed Binding?
  • Warum @EnableConfigurationProperties oder @ConfigurationPropertiesScan aktivieren?

Falle: @Value plus SpEL für Listen von YAML-Maps.

Merksatz: Ein Flag kann @Value sein; eine Konfigurationsgruppe sollte @ConfigurationProperties sein.

Lesen: Externe Konfiguration

12. How do profiles work in production?

Deutsch

Wie funktionieren Profiles in Produktion?

Level: Mid · Listen for: spring.profiles.active; don’t use profiles as a feature flag dump

Niveau: Mid · Darauf hören sie: spring.profiles.active; Profiles nicht als Feature-Flag-Halde

Model answer

Profiles activate beans and property documents (application-prod.yml). Set spring.profiles.active (env var, not a committed secret file). You can combine profiles (prod,kafka).

I use profiles for environment differences: datasources, log levels, OAuth issuers. I do not use them as a product-feature matrix — that becomes untestable.

@Profile("!test") and profile-specific @Beans must stay obvious. Tests should set profiles explicitly (@ActiveProfiles).

Follow-ups

  • Profile groups in Boot?
  • spring.config.activate.on-profile vs @Profile?

Trap: a default dev profile that silently runs in production.

Memory sentence: Profiles select an environment; they are not a second programming language.

Study: Profiles

Musterantwort

Profiles aktivieren Beans und Property-Dokumente (application-prod.yml). Setze spring.profiles.active (Umgebungsvariable, keine Secret-Datei im Repo). Du kannst Profiles kombinieren (prod,kafka).

Ich nutze Profiles für Umgebungsunterschiede: DataSources, Log-Level, OAuth-Issuer. Nicht als Produkt-Feature-Matrix — das wird untestbar.

@Profile("!test") und profilspezifische @Beans müssen offensichtlich bleiben. Tests sollen Profiles explizit setzen (@ActiveProfiles).

Nachfragen

  • Profile Groups in Boot?
  • spring.config.activate.on-profile vs. @Profile?

Falle: ein Default-dev-Profile, das still in Produktion läuft.

Merksatz: Profiles wählen eine Umgebung; sie sind keine zweite Programmiersprache.

Lesen: Profiles

13. Component scanning: why is the package of the main class sacred?

Deutsch

Component Scanning: warum ist das Package der Main-Klasse heilig?

Level: Mid · Listen for: default scan from @SpringBootApplication

Niveau: Mid · Darauf hören sie: Default-Scan ab @SpringBootApplication

Model answer

@SpringBootApplication scans the package of the annotated class and below. If your application class sits in com.acme.app and a @Service lives in com.acme.billing, it is not a bean unless you add scanBasePackages.

The usual layout: one main class at the root (com.acme.app.Application) and all modules underneath. Multi-module builds still need that root or an explicit scan.

Follow-ups

  • What does @SpringBootApplication actually compose?
  • Filters: excludeFilters for tests?

Trap: putting Application in com.acme.app.web and wondering why services vanished.

Memory sentence: Scan starts at the main class package unless you say otherwise.

Study: Component scanning

Musterantwort

@SpringBootApplication scannt das Package der annotierten Klasse und darunter. Sitzt deine Application-Klasse in com.acme.app und ein @Service in com.acme.billing, ist das kein Bean — außer du setzt scanBasePackages.

Übliches Layout: eine Main-Klasse an der Wurzel (com.acme.app.Application) und alle Module darunter. Multi-Module-Builds brauchen trotzdem diese Wurzel oder einen expliziten Scan.

Nachfragen

  • Was setzt @SpringBootApplication tatsächlich zusammen?
  • Filter: excludeFilters für Tests?

Falle: Application nach com.acme.app.web legen und sich wundern, warum die Services verschwunden sind.

Merksatz: Der Scan startet am Package der Main-Klasse, außer du sagst etwas anderes.

Lesen: Component Scanning

14. What is a BeanPostProcessor vs a BeanFactoryPostProcessor?

Deutsch

Was ist ein BeanPostProcessor vs. ein BeanFactoryPostProcessor?

Level: Senior · Listen for: definitions vs instances

Niveau: Senior · Darauf hören sie: Definitionen vs. Instanzen

Model answer

A BeanFactoryPostProcessor runs after definitions are loaded and before beans are created. It can change recipes (PropertySourcesPlaceholderConfigurer resolving ${}).

A BeanPostProcessor runs around each instance: wrap with a proxy (@Transactional, @Async, @Retryable), inject @Autowired points, apply @PostConstruct.

You rarely write these in app code. You need the distinction to understand why @Transactional is a proxy and why placeholders cannot be resolved “too late”.

Follow-ups

  • Why must BeanFactoryPostProcessor beans be defined carefully (no eager deps on normal beans)?
  • BeanDefinitionRegistryPostProcessor?

Trap: trying to @Autowired a normal service into a BeanFactoryPostProcessor and creating early init cycles.

Memory sentence: Factory post-processors edit recipes; bean post-processors wrap instances.

Study: Bean lifecycle

Musterantwort

Ein BeanFactoryPostProcessor läuft, nachdem die Definitionen geladen sind und bevor Beans erzeugt werden. Er kann Rezepte ändern (PropertySourcesPlaceholderConfigurer löst ${} auf).

Ein BeanPostProcessor läuft an jeder Instanz: wrappt mit einem Proxy (@Transactional, @Async, @Retryable), injiziert @Autowired-Punkte, wendet @PostConstruct an.

Im App-Code schreibst du sie selten. Die Unterscheidung brauchst du, um zu verstehen, warum @Transactional ein Proxy ist und warum Placeholder nicht „zu spät“ aufgelöst werden können.

Nachfragen

  • Warum müssen BeanFactoryPostProcessor-Beans vorsichtig definiert werden (keine eager Abhängigkeiten zu normalen Beans)?
  • BeanDefinitionRegistryPostProcessor?

Falle: einen normalen Service per @Autowired in einen BeanFactoryPostProcessor stecken und damit Early-Init-Zyklen bauen.

Merksatz: Factory-Post-Processor ändern Rezepte; Bean-Post-Processor wrappen Instanzen.

Lesen: Bean Lifecycle

15. @Lazy — what does it actually delay?

Deutsch

@Lazy — was verzögert es wirklich?

Level: Mid · Listen for: creation time, not proxy cost; cycles

Niveau: Mid · Darauf hören sie: Erzeugungszeitpunkt, nicht Proxy-Kosten; Zyklen

Model answer

@Lazy on a bean delays instantiation until first use. @Lazy on an injection point injects a proxy that resolves the real bean later.

Use it for expensive optional collaborators or to break a cycle temporarily. Do not sprinkle @Lazy to hide a slow startup you have not measured. First-request latency just moves to production traffic.

Boot also has spring.main.lazy-initialization=true for the whole context — useful for tests or CLI tools, risky for web apps that want fail-fast.

Follow-ups

  • Does @Lazy stop a @PostConstruct from running at startup? (yes, until first use)
  • Interaction with @Transactional proxies?

Trap: lazy as a substitute for fixing circular dependencies.

Memory sentence: Lazy delays creation; it does not make a bean cheaper.

Study: Startup

Musterantwort

@Lazy auf einem Bean verzögert die Instanziierung bis zur ersten Nutzung. @Lazy auf einem Injection Point injiziert einen Proxy, der den echten Bean später auflöst.

Nutze es für teure optionale Abhängigkeiten oder um einen Zyklus vorübergehend zu brechen. Klebe nicht überall @Lazy hin, um einen langsamen Start zu verstecken, den du nicht gemessen hast. Die Latenz der ersten Requests wandert dann nur in den Produktions-Traffic.

Boot hat außerdem spring.main.lazy-initialization=true für den ganzen Context — nützlich für Tests oder CLI-Tools, riskant für Web-Apps, die fail-fast wollen.

Nachfragen

  • Verhindert @Lazy, dass @PostConstruct beim Start läuft? (ja, bis zur ersten Nutzung)
  • Zusammenspiel mit @Transactional-Proxies?

Falle: Lazy als Ersatz dafür, zirkuläre Abhängigkeiten zu fixen.

Merksatz: Lazy verzögert die Erzeugung; es macht den Bean nicht billiger.

Lesen: Start

16. Why must singleton beans be thread-safe?

Deutsch

Warum müssen Singleton-Beans thread-safe sein?

Level: Mid · Listen for: shared mutable state; request scope alternative

Niveau: Mid · Darauf hören sie: geteilter veränderlicher State; Request Scope als Alternative

Model answer

A singleton is one instance for all requests. Fields are shared memory. A List or Map on a @Service is a race unless it is concurrent, immutable, or the bean is not a singleton.

Keep services stateless: collaborators + no mutable fields. Put per-request data in method arguments, SecurityContext, or request-scoped beans.

Follow-ups

  • Is a String field a race? (if reassigned without visibility, yes; if final, no)
  • Prototype beans and thread safety?

Trap: caching results in an ArrayList field on a service.

Memory sentence: Singletons are shared; mutable fields are shared mutable state.

Study: Bean scopes

Musterantwort

Ein Singleton ist eine Instanz für alle Requests. Felder sind Shared Memory. Eine List oder Map auf einem @Service ist eine Race Condition — außer sie ist concurrent, immutable oder der Bean ist kein Singleton.

Halte Services stateless: Abhängigkeiten + keine veränderlichen Felder. Per-Request-Daten gehören in Methodenargumente, SecurityContext oder Request-scoped Beans.

Nachfragen

  • Ist ein String-Feld eine Race Condition? (wenn ohne Visibility neu zugewiesen, ja; wenn final, nein)
  • Prototype-Beans und Thread Safety?

Falle: Ergebnisse in einem ArrayList-Feld auf einem Service cachen.

Merksatz: Singletons sind geteilt; veränderliche Felder sind geteilter veränderlicher State.

Lesen: Bean Scopes