Files
spring-boot-demo/core-beans/README.md
T

5.7 KiB

core-beans

Companion project for two articles on ankurm.com.

Article What it demonstrates
Spring Bean Scopes: Singleton, Prototype, Request, Session and the Prototype-in-Singleton Trap instance counts for every scope, five ways to get a fresh prototype inside a singleton, a singleton that leaks one caller's data into another's, and request scope without a proxy failing at start-up
Spring Bean Lifecycle in Boot 4: @PostConstruct, InitializingBean, SmartLifecycle and Shutdown Order every callback in order from a real run, @PostConstruct running before the proxy exists, the non-static BeanPostProcessor warning, SmartLifecycle phases measured, and a request in flight during graceful shutdown with virtual threads

Every console block, exception message and count quoted in those articles came out of output/, and every file there is regenerated by one script. Most are written by the test suite, so if a claim stops being true the build goes red.

There is deliberately no docs/ folder: the deeper material lives in collapsible "going deeper" sections inside the articles themselves, next to the paragraph each one extends.

Versions

Spring Boot 4.1.1
Spring Framework 7.0.9
JDK 25 (Temurin 25.0.4.1+1)
Maven 3.9

Quickstart

export JAVA_HOME=/path/to/jdk-25
mvn test                       # runs the scenarios and rewrites the test-written files in output/
./scripts/run-all.sh           # everything, including the script-captured files

Source layout

Package What it holds
scopes/ singleton, @Lazy, prototype, scoped-prototype and the five ways a singleton can obtain a prototype; the shared-state greeter
web/ @RequestScope, @SessionScope, @ApplicationScope beans and a diagnostic /scopes controller, plus the un-proxied request bean that fails at start-up
lifecycle/ KitchenSink (every callback), the post-processor traps, PhasedWorker and NeverStops for SmartLifecycle
shutdown/ a web application with a /slow endpoint and two SmartLifecycle beans at different phases

Endpoints

Both endpoints exist only to be called by the tests. They have no authorisation. Delete them before shipping.

Endpoint Application Purpose
GET /scopes WebScopesApp request, session and application instance serials, and the injected proxy class
GET /slow?ms=1500 ShutdownApp sleeps, so a request can be in flight when the context closes

Captured output

Files 01-17 and 19 (tests) and 18 (capture-metadata.sh). Timing rows assert coarse thresholds, not exact milliseconds; treat them as indicative.

File What it shows
01-instance-counts.txt How many instances did the container really construct?
02-prototype-destroy.txt @PreDestroy on a singleton and on a prototype, then context.close()
03-prototype-in-singleton.txt A singleton calls use() five times. How many prototype instances did it touch?
04-singleton-thread-safety.txt Two threads call the same singleton; a latch forces the interleaving
05-web-scopes.txt request, session and application scope over real HTTP
06-request-scope-without-proxy.txt A request-scoped bean (no proxy) injected into a singleton
07-full-callback-order.txt Every callback for one bean, from constructor to the last destroy hook (SpringApplication, no web server)
08-non-static-bpp-warning.txt A BeanPostProcessor declared with a non-static @Bean method
09-postconstruct-before-proxy.txt @PostConstruct runs before the @Async proxy exists
10-postconstruct-failure.txt An exception thrown from @PostConstruct
11-smartlifecycle-phases.txt Three SmartLifecycle beans registered in the order 300, 100, 200
12-blocking-vs-async-stop.txt Three SmartLifecycle beans in the SAME phase, each needing 400 ms to stop
13-plain-lifecycle.txt Lifecycle vs SmartLifecycle: who starts at refresh()?
14-shutdown-timeout.txt A SmartLifecycle whose stop(callback) never calls the callback, timeout 500 ms
15-smartlifecycle-beans-in-boot.txt Every SmartLifecycle bean in a Boot web application, highest phase (stops first) at the top
16-graceful-shutdown-in-flight.txt A /slow?ms=1500 request is in flight when the context closes
17-worker-phase-vs-web-server.txt SmartLifecycle beans with the default phase and with phase 1000, while a request is in flight
18-property-defaults.txt Property defaults read from spring-configuration-metadata.json (Boot 4.1.1 jars)
19-bean-post-processors.txt The BeanPostProcessors registered in a plain Spring Boot context, in the order they run

Licence

MIT, see the repository root.