English + German
English stays on the page. Click the button to show the German text under each question.
Spring Boot
Interviewers use Boot to see whether you understand auto-configuration, or whether you only know “add the starter”.
Deep chapters: Week 3.
Deutsch
Spring Boot
Interviewer nutzen Boot, um zu sehen, ob du auto-configuration verstehst — oder ob du nur „den Starter dazupacken“ kannst.
Vertiefung: Woche 3.
1. What does Spring Boot add on top of Spring?
Deutsch
Was legt Spring Boot über Spring drauf?
Level: Junior · Listen for: opinionated defaults, not a different IoC container
Niveau: Junior · Darauf hören sie: opinionated Defaults, nicht ein anderer IoC-Container
Model answer
Spring is the container and the programming model. Boot adds:
- starters (dependency bills)
- auto-configuration (conditional beans)
- an embedded server
- a production-ready fat jar
- Actuator
- an opinionated
Environment(application.yml, profiles, relaxed binding)
The beans are still Spring beans. Boot decides which ones exist so you do not write a DataSource @Bean every time.
Follow-ups
- Can you use Spring MVC without Boot? (yes)
- What is the Spring Boot starter parent / BOM?
Trap: “Boot is a different framework than Spring.”
Memory sentence: Boot configures Spring for you; it does not replace the container.
Study: Boot mental model
Musterantwort
Spring ist der Container und das Programmiermodell. Boot legt dazu:
- Starter (kuratierte Dependency-Sets)
- auto-configuration (bedingte Beans)
- einen embedded Server
- ein production-ready fat jar
- Actuator
- ein opinionated
Environment(application.yml, Profiles, relaxed Binding)
Die Beans sind weiterhin Spring-Beans. Boot entscheidet, welche existieren — du schreibst nicht jedes Mal eine DataSource-@Bean.
Nachfragen
- Kannst du Spring MVC ohne Boot nutzen? (ja)
- Was ist das Spring Boot starter parent / BOM?
Falle: „Boot ist ein anderes Framework als Spring.“
Merksatz: Boot konfiguriert Spring für dich; es ersetzt den Container nicht.
Lesen: Boot-Mental-Model
2. What is inside @SpringBootApplication?
Deutsch
Was steckt in @SpringBootApplication?
Level: Mid · Listen for: three annotations
Niveau: Mid · Darauf hören sie: drei Annotationen
Model answer
It is a composed annotation:
@SpringBootConfiguration(@Configuration)@EnableAutoConfiguration@ComponentScan(plus some Boot filters)
So the main class is a configuration class, it turns on auto-config, and it scans its package tree. Putting it in the wrong package is a common “beans missing” outage.
Follow-ups
@SpringBootConfigurationvs@Configuration?- How do you exclude one auto-config class?
Trap: adding another @ComponentScan that accidentally narrows or duplicates the scan.
Memory sentence: Main class = configuration + auto-config + scan.
Study: Boot mental model
Musterantwort
Es ist eine zusammengesetzte Annotation:
@SpringBootConfiguration(@Configuration)@EnableAutoConfiguration@ComponentScan(plus ein paar Boot-Filter)
Die Main-Klasse ist also eine Configuration-Klasse: sie schaltet auto-configuration an und scannt ihren Package-Baum. Liegt sie im falschen Package, fehlen Beans — ein klassischer Ausfall.
Nachfragen
@SpringBootConfigurationvs@Configuration?- Wie excludest du eine Auto-Config-Klasse?
Falle: noch ein @ComponentScan dazulegen, das den Scan versehentlich verengt oder verdoppelt.
Merksatz: Main-Klasse = configuration + auto-config + scan.
Lesen: Boot-Mental-Model
3. What is a starter, technically?
Deutsch
Was ist ein Starter technisch?
Level: Mid · Listen for: BOM + transitive deps, not “magic beans”
Niveau: Mid · Darauf hören sie: BOM + transitive Dependencies, nicht „magische Beans“
Model answer
A starter is a dependency descriptor: it pulls a curated set of libraries (and usually an auto-config module). spring-boot-starter-data-jpa does not contain your repositories; it brings Hibernate, Spring Data JPA, and transaction APIs, and it puts auto-config on the classpath.
The BOM (spring-boot-dependencies) aligns versions so you do not pick a random Hibernate.
You can write a custom starter: a jar with AutoConfiguration.imports and a pom that others depend on.
Follow-ups
- Starter vs the
spring-boot-autoconfiguremodule? - Why can two starters conflict?
Trap: “the starter is the annotation.”
Memory sentence: Starters are dependency bundles that make auto-config eligible.
Study: Starters
Musterantwort
Ein Starter ist ein Dependency-Descriptor: er zieht ein kuratiertes Set an Libraries (und meist ein Auto-Config-Modul). spring-boot-starter-data-jpa enthält nicht deine Repositories; er bringt Hibernate, Spring Data JPA und Transaction-APIs und legt Auto-Config auf den Classpath.
Das BOM (spring-boot-dependencies) hält die Versionen zusammen, damit du nicht irgendein Hibernate nimmst.
Du kannst einen eigenen Starter schreiben: ein Jar mit AutoConfiguration.imports und einem pom, von dem andere abhängen.
Nachfragen
- Starter vs das Modul
spring-boot-autoconfigure? - Warum können zwei Starter kollidieren?
Falle: „der Starter ist die Annotation.“
Merksatz: Starter sind Dependency-Bundles, durch die Auto-Config erst greifen kann.
Lesen: Starters
4. How does auto-configuration decide to create a bean?
Deutsch
Wie entscheidet auto-configuration, ob eine Bean erzeugt wird?
Level: Mid · Listen for: classpath, properties, @ConditionalOnMissingBean, back-off
Niveau: Mid · Darauf hören sie: Classpath, Properties, @ConditionalOnMissingBean, back-off
Model answer
Auto-config classes are loaded from META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (Boot 3). Each class is full of @Conditional*:
@ConditionalOnClass— library present@ConditionalOnMissingBean— you did not already define one (back-off)@ConditionalOnProperty— a flag@ConditionalOnWebApplication, and so on
If you define a DataSource @Bean, Boot’s default DataSource auto-config backs off. That is the extension model: replace a default by exposing your own bean of the same type.
Follow-ups
- Order /
@AutoConfiguration(after = …)? - Why can “I added a bean” silently disable a whole feature?
Trap: fighting auto-config with random @Beans you do not understand.
Memory sentence: Auto-config is conditional; your bean of the same type is how you opt out.
Study: Auto-configuration
Musterantwort
Auto-Config-Klassen kommen aus META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (Boot 3). Jede Klasse steckt voller @Conditional*:
@ConditionalOnClass— Library vorhanden@ConditionalOnMissingBean— du hast noch keine definiert (back-off)@ConditionalOnProperty— ein Flag@ConditionalOnWebApplication, und so weiter
Wenn du eine DataSource-@Bean definierst, macht Boots Default-DataSource-Auto-Config back-off. Das ist das Erweiterungsmodell: Default ersetzen, indem du selbst eine Bean desselben Typs bereitstellst.
Nachfragen
- Reihenfolge /
@AutoConfiguration(after = …)? - Warum kann „ich habe eine Bean dazugelegt“ stillschweigend ein ganzes Feature abschalten?
Falle: Auto-Config mit wilden @Beans bekämpfen, die du nicht verstehst.
Merksatz: Auto-config ist conditional; mit einer Bean desselben Typs steigst du aus.
Lesen: Auto-configuration
5. How do you debug “why was this bean created / not created?”
Deutsch
Wie debuggst du „warum wurde diese Bean erzeugt / nicht erzeugt?“
Level: Mid · Listen for: conditions report, not guesswork
Niveau: Mid · Darauf hören sie: Conditions-Report, kein Raten
Model answer
I do not guess. I use:
debug=trueor--debug— auto-config report in the log (positive / negative matches)- Actuator
/actuator/conditionsand/actuator/beans @SpringBootTestwith printed conditions in failing tests
Negative matches tell you which condition failed (OnClass vs OnMissingBean). That is usually enough to see a missing starter or your own bean causing back-off.
Follow-ups
ConditionEvaluationReport?- Why is
/actuator/beansdisabled by default in prod?
Trap: adding @ComponentScan as the first “fix” for a missing bean.
Memory sentence: The conditions report is the source of truth for auto-config.
Study: Auto-configuration debugging
Musterantwort
Ich rate nicht. Ich nutze:
debug=trueoder--debug— Auto-Config-Report im Log (positive / negative Matches)- Actuator
/actuator/conditionsund/actuator/beans @SpringBootTestmit ausgegebenen Conditions in fehlschlagenden Tests
Negative Matches zeigen, welche Condition fehlgeschlagen ist (OnClass vs OnMissingBean). Das reicht meist, um einen fehlenden Starter oder deine eigene Bean als Ursache für back-off zu sehen.
Nachfragen
ConditionEvaluationReport?- Warum ist
/actuator/beansin Prod standardmäßig aus?
Falle: @ComponentScan als ersten „Fix“ für eine fehlende Bean dazulegen.
Merksatz: Der Conditions-Report ist für Auto-Config die Wahrheit.
Lesen: Auto-configuration debuggen
6. What is Actuator for? Which endpoints matter in production?
Deutsch
Wozu ist Actuator da? Welche Endpoints zählen in Produktion?
Level: Mid · Listen for: health for probes, info, metrics, not exposing everything
Niveau: Mid · Darauf hören sie: Health für Probes, Info, Metrics — nicht alles exponieren
Model answer
Actuator is production diagnostics: health, metrics, info, env, beans, mappings, threaddump, loggers, conditions.
In production I expose health (and maybe info) over HTTP for Kubernetes liveness/readiness, and I keep the rest behind auth or only on an internal port. env and beans leak secrets and internals.
Health groups split liveness (process is up) from readiness (DB is reachable). A DB outage should fail readiness, not necessarily kill the process (liveness).
Follow-ups
- Custom
HealthIndicator? - Micrometer vs
/metrics?
Trap: management.endpoints.web.exposure.include=* on the public internet.
Memory sentence: Actuator is the flight recorder; expose health, protect the rest.
Study: Actuator
Musterantwort
Actuator ist Diagnose für Produktion: Health, Metrics, Info, Env, Beans, Mappings, Threaddump, Loggers, Conditions.
In Produktion exponiere ich health (und vielleicht info) über HTTP für Kubernetes Liveness/Readiness, den Rest halte ich hinter Auth oder nur auf einem internen Port. env und beans geben Secrets und Interna preis.
Health-Groups trennen Liveness (Prozess läuft) von Readiness (DB ist erreichbar). Ein DB-Ausfall soll Readiness failen lassen, den Prozess nicht unbedingt killen (Liveness).
Nachfragen
- Eigener
HealthIndicator? - Micrometer vs
/metrics?
Falle: management.endpoints.web.exposure.include=* im öffentlichen Internet.
Merksatz: Actuator ist der Flugschreiber; Health exponieren, den Rest schützen.
Lesen: Actuator
7. CommandLineRunner vs ApplicationRunner vs ApplicationReadyEvent?
Deutsch
CommandLineRunner vs ApplicationRunner vs ApplicationReadyEvent?
Level: Mid · Listen for: after context is up; not for long work
Niveau: Mid · Darauf hören sie: nachdem der Context steht; nicht für lange Arbeit
Model answer
Both runners run once after the context is loaded, before the app is considered fully started. ApplicationRunner gets parsed ApplicationArguments; CommandLineRunner gets raw strings.
ApplicationReadyEvent is an event after the application is ready (web server started). ApplicationStartedEvent is slightly earlier.
I use them for one-shot setup (seed data in dev, schema checks). I do not run multi-minute jobs there — the orchestrator/K8s will think startup hung. Long work belongs in a scheduler, a consumer, or a separate job.
Follow-ups
- Order of multiple runners?
- What happens if a runner throws?
Trap: heavy migration in a runner on every pod start.
Memory sentence: Runners are startup hooks, not background workers.
Study: Startup
Musterantwort
Beide Runner laufen einmal, nachdem der Context geladen ist, bevor die App als vollständig gestartet gilt. ApplicationRunner bekommt geparste ApplicationArguments; CommandLineRunner bekommt rohe Strings.
ApplicationReadyEvent ist ein Event, nachdem die Anwendung bereit ist (Web-Server gestartet). ApplicationStartedEvent kommt etwas früher.
Ich nutze sie für einmaliges Setup (Seed-Daten in dev, Schema-Checks). Ich starte dort keine Jobs, die Minuten dauern — Orchestrator/K8s denkt, der Startup hängt. Lange Arbeit gehört in einen Scheduler, einen Consumer oder einen eigenen Job.
Nachfragen
- Reihenfolge mehrerer Runner?
- Was passiert, wenn ein Runner wirft?
Falle: schwere Migration in einem Runner bei jedem Pod-Start.
Merksatz: Runner sind Startup-Hooks, keine Worker im Hintergrund.
Lesen: Startup
8. How does the embedded server work? What is a fat jar?
Deutsch
Wie funktioniert der embedded Server? Was ist ein fat jar?
Level: Mid · Listen for: executable jar with nested deps; main starts Tomcat
Niveau: Mid · Darauf hören sie: executable Jar mit nested Dependencies; main startet Tomcat
Model answer
Boot apps call SpringApplication.run, which creates the context and starts an embedded Tomcat/Jetty/Undertow as beans. You do not deploy a WAR unless you choose to.
The fat (uber) jar contains your classes plus nested dependency jars and a custom JarLauncher. java -jar app.jar is enough. The layer layout also helps Docker layer caching.
You still need an external process manager (systemd, Kubernetes) for restart, health, and logs. The fat jar is not a whole production platform.
Follow-ups
loader.mainvs yourmain?- When do you still build a WAR?
Trap: “Boot cannot run on an external Tomcat.” It can; it is just not the default.
Memory sentence: Boot starts the server inside the JVM; the fat jar is how you ship that JVM app.
Study: Boot mental model
Musterantwort
Boot-Apps rufen SpringApplication.run auf — das erzeugt den Context und startet embedded Tomcat/Jetty/Undertow als Beans. Ein WAR deployst du nur, wenn du dich bewusst dafür entscheidest.
Das fat (uber) jar enthält deine Klassen plus nested Dependency-Jars und einen eigenen JarLauncher. java -jar app.jar reicht. Das Layer-Layout hilft außerdem beim Docker-Layer-Caching.
Du brauchst trotzdem einen externen Prozessmanager (systemd, Kubernetes) für Restart, Health und Logs. Das fat jar ist keine komplette Produktionsplattform.
Nachfragen
loader.mainvs deinemain?- Wann baust du trotzdem ein WAR?
Falle: „Boot kann nicht auf einem externen Tomcat laufen.“ Kann es; es ist nur nicht der Default.
Merksatz: Boot startet den Server in der JVM; das fat jar ist, wie du diese JVM-App auslieferst.
Lesen: Boot-Mental-Model
9. Property sources: who wins?
Deutsch
Property Sources: wer gewinnt?
Level: Mid · Listen for: command line / env vars beat application.yml
Niveau: Mid · Darauf hören sie: Kommandozeile / Env Vars schlagen application.yml
Model answer
Boot has a documented precedence. In practice:
- command-line args
- OS environment variables / Kubernetes env
- profile-specific
application-{profile}.yml application.ymlin the jar- defaults in
@ConfigurationProperties
Secrets belong in the environment or a secret store, not in git YAML. Relaxed binding maps APP_TOKEN to app.token.
If a value “does not bind”, I print the env via a safe debug path (never logs of secrets) or a unit test with @SpringBootTest + application-test.yml.
Follow-ups
optional:configtree/ Kubernetes volume secrets?- Why can YAML maps surprise relaxed binding?
Trap: committing application-prod.yml with passwords.
Memory sentence: The environment overrides the jar; secrets stay out of git.
Study: External configuration
Musterantwort
Boot hat eine dokumentierte Rangfolge. In der Praxis:
- Kommandozeilenargumente
- OS-Umgebungsvariablen / Kubernetes Env
- profilspezifisches
application-{profile}.yml application.ymlim Jar- Defaults in
@ConfigurationProperties
Secrets gehören in die Environment oder einen Secret Store, nicht ins YAML in Git. Relaxed Binding mappt APP_TOKEN auf app.token.
Wenn ein Wert „nicht bindet“, drucke ich die Env über einen sicheren Debug-Pfad (nie Logs mit Secrets) oder einen Unit-Test mit @SpringBootTest + application-test.yml.
Nachfragen
optional:configtree/ Kubernetes Volume Secrets?- Warum können YAML-Maps relaxed Binding überraschen?
Falle: application-prod.yml mit Passwörtern committen.
Merksatz: Die Environment überschreibt das Jar; Secrets bleiben raus aus Git.
Lesen: Externe Konfiguration
10. How would you write a custom auto-configuration?
Deutsch
Wie würdest du eine eigene auto-configuration schreiben?
Level: Senior · Listen for: @AutoConfiguration, conditions, imports file, back-off
Niveau: Senior · Darauf hören sie: @AutoConfiguration, Conditions, imports-Datei, back-off
Model answer
A library jar should not force @ComponentScan on consumers. It should ship:
- an
@AutoConfigurationclass with@ConditionalOnClassand@ConditionalOnMissingBean - an entry in
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports - a
@ConfigurationPropertiestype - tests with
ApplicationContextRunner
Users opt in by adding the starter. They override by declaring their own bean. That is how Boot itself is built.
Follow-ups
- Why not
@ComponentScana library package from the starter? @AutoConfigurationvs@Configuration+@Import?
Trap: scanning library packages from the application — you steal the user’s component names and cannot back off.
Memory sentence: Libraries auto-configure; they do not scan the user’s classpath.
Study: Auto-configuration
Musterantwort
Ein Library-Jar sollte Nutzern kein @ComponentScan aufzwingen. Es sollte mitliefern:
- eine
@AutoConfiguration-Klasse mit@ConditionalOnClassund@ConditionalOnMissingBean - einen Eintrag in
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports - einen
@ConfigurationProperties-Typ - Tests mit
ApplicationContextRunner
Wer die Library nutzt, holt das Feature per Starter. Überschreiben geht über die eigene Bean. So ist Boot selbst gebaut.
Nachfragen
- Warum nicht ein Library-Package vom Starter aus per
@ComponentScanscannen? @AutoConfigurationvs@Configuration+@Import?
Falle: Library-Packages aus der Anwendung scannen — du klaust die Component-Namen der Nutzer und kannst kein back-off mehr machen.
Merksatz: Libraries machen auto-configuration; sie scannen nicht den Classpath der Nutzer.
Lesen: Auto-configuration
11. Spring Boot 3 vs 2 — what must you mention?
Deutsch
Spring Boot 3 vs 2 — was musst du nennen?
Level: Mid · Listen for: Jakarta, Java 17, properties, security DSL
Niveau: Mid · Darauf hören sie: Jakarta, Java 17, Properties, Security-DSL
Model answer
Boot 3 requires Java 17+ and Jakarta EE (jakarta.* instead of javax.*). Hibernate 6, a new Security lambda DSL as the baseline, observability with Micrometer Tracing, and AutoConfiguration.imports instead of spring.factories for auto-config.
If I migrate, I treat javax → jakarta as a mechanical but total change, then I fix Security config, property renames, and tests. I do not migrate and add features in the same PR.
Follow-ups
- Native images / AOT?
- Boot 4 direction, if you have read the migration notes?
Trap: mixing javax.persistence and jakarta.persistence on the classpath.
Memory sentence: Boot 3 is Jakarta + Java 17; the container ideas did not change.
Study: Spring Boot 3 to 4
Musterantwort
Boot 3 braucht Java 17+ und Jakarta EE (jakarta.* statt javax.*). Hibernate 6, eine neue Security-Lambda-DSL als Standard, Observability mit Micrometer Tracing, und AutoConfiguration.imports statt spring.factories für Auto-Config.
Wenn ich migriere, behandle ich javax → jakarta als mechanische, aber totale Änderung, dann fixe ich Security-Config, Property-Umbenennungen und Tests. Ich migriere nicht und baue Features im selben PR.
Nachfragen
- Native Images / AOT?
- Richtung Boot 4, falls du die Migrationsdoku gelesen hast?
Falle: javax.persistence und jakarta.persistence auf dem Classpath mischen.
Merksatz: Boot 3 ist Jakarta + Java 17; die Container-Ideen haben sich nicht geändert.
Lesen: Spring Boot 3 nach 4
12. Fail-fast startup vs lazy initialization?
Deutsch
Fail-fast Startup vs lazy initialization?
Level: Mid · Listen for: web apps want fail-fast
Niveau: Mid · Darauf hören sie: Web-Apps wollen fail-fast
Model answer
By default Boot creates singletons at startup. A missing DataSource, a bad property, or a broken @Transactional proxy shows up before traffic. That is what you want for a server.
spring.main.lazy-initialization=true makes startup fast and moves failures to the first request. Useful for tests and some CLIs. Dangerous for HTTP services and Kubernetes if readiness is already green.
I keep web apps eager, and I use Actuator readiness so a pod that cannot talk to the DB does not receive traffic.
Follow-ups
- How does this interact with
@Lazyon one bean? - Startup time vs first-request latency?
Trap: turning on global lazy to hide a 20-second auto-config you have not measured.
Memory sentence: Servers should fail at boot; lazy only moves the failure into a user request.
Study: Startup
Musterantwort
Defaultmäßig erzeugt Boot Singletons beim Startup. Eine fehlende DataSource, eine kaputte Property oder ein kaputter @Transactional-Proxy zeigt sich, bevor Traffic kommt. Das willst du bei einem Server.
spring.main.lazy-initialization=true macht den Startup schnell und schiebt Fehler auf den ersten Request. Nützlich für Tests und manche CLIs. Gefährlich für HTTP-Services und Kubernetes, wenn Readiness schon grün ist.
Web-Apps halte ich eager, und ich nutze Actuator Readiness, damit ein Pod, der die DB nicht erreicht, keinen Traffic bekommt.
Nachfragen
- Wie spielt das mit
@Lazyauf einer einzelnen Bean zusammen? - Startup-Zeit vs Latenz des ersten Requests?
Falle: globales Lazy anmachen, um eine 20-Sekunden-Auto-Config zu verstecken, die du nicht gemessen hast.
Merksatz: Server sollen beim Startup failen; lazy schiebt den Fehler nur in einen Request vom User.
Lesen: Startup
13. How do you structure a non-trivial Boot project?
Deutsch
Wie strukturierst du ein größeres Boot-Projekt?
Level: Senior · Listen for: package by feature, one main class at the root
Niveau: Senior · Darauf hören sie: package by feature, eine Main-Klasse im Root-Package
Model answer
I prefer package by feature (order, payment, customer) over package by layer as the first split, with layer types inside a feature if the team wants. The main class sits at the root package.
Configuration: one @ConfigurationProperties per feature prefix. No giant Util package. Persistence stays inside the feature; the API layer talks DTOs, not entities.
Modules (Gradle) come when the team or the bounded contexts are real, not as a first gesture.
Follow-ups
- Hexagonal vs layered in a Boot app?
- Where do you put
@Entityclasses?
Trap: 15 packages named controller, service, repo with 200 files each and no boundaries.
Memory sentence: Feature packages first; the main class anchors the scan.
Study: Component scanning
Musterantwort
Ich bevorzuge package by feature (order, payment, customer) gegenüber package by layer als ersten Schnitt, mit Layer-Typen im Feature, wenn das Team das will. Die Main-Klasse sitzt im Root-Package.
Konfiguration: ein @ConfigurationProperties pro Feature-Prefix. Kein Riesen-Util-Package. Persistenz bleibt im Feature; die API-Schicht spricht DTOs, nicht Entities.
Module (Gradle) kommen, wenn Team oder Bounded Contexts echt sind — nicht als erster Schachzug.
Nachfragen
- Hexagonal vs layered in einer Boot-App?
- Wohin kommen
@Entity-Klassen?
Falle: 15 Packages namens controller, service, repo mit je 200 Dateien und ohne Grenzen.
Merksatz: Feature-Packages zuerst; die Main-Klasse ankert den Scan.
Lesen: Component-Scan
14. What do you check when a Boot app “starts but every request is 404”?
Deutsch
Was prüfst du, wenn eine Boot-App „startet, aber jeder Request 404 ist“?
Level: Mid · Listen for: scan path, dispatcher, context path, security
Niveau: Mid · Darauf hören sie: Scan-Pfad, Dispatcher, Context Path, Security
Model answer
Order:
- Is the controller a bean? (package scan,
@RestController) - Actuator
/mappings— is the route registered? server.servlet.context-pathand reverse-proxy prefix- Spring Security catching it as 401/403 misread as 404
- Wrong HTTP method or
producesnot matchingAccept
I do not add random @ComponentScan until /mappings proves the handler is missing.
Follow-ups
- Two
DispatcherServlets? spring.mvc.servlet.path?
Trap: blaming Tomcat when Security or the scan path is the cause.
Memory sentence: If it is 404, first ask whether the handler is a bean and whether /mappings shows it.
Study: MVC mental model
Musterantwort
Reihenfolge:
- Ist der Controller eine Bean? (Package-Scan,
@RestController) - Actuator
/mappings— ist die Route registriert? server.servlet.context-pathund Reverse-Proxy-Prefix- Spring Security fängt den Request als 401/403 — das liest du fälschlich als 404
- Falsche HTTP-Methode oder
producespasst nicht zuAccept
Ich packe kein zufälliges @ComponentScan drauf, bis /mappings zeigt, dass der Handler fehlt.
Nachfragen
- Zwei
DispatcherServlets? spring.mvc.servlet.path?
Falle: Tomcat die Schuld geben, wenn Security oder der Scan-Pfad die Ursache ist.
Merksatz: Bei 404 zuerst fragen, ob der Handler eine Bean ist und ob /mappings ihn zeigt.
Lesen: MVC-Mental-Model