I Built a Visualizer for the Spring Bean Lifecycle (Context Startup, @PostConstruct, Prototype Beans)

java dev.to

Spring does a surprising amount of work between "I found a @Component" and "the bean is ready to inject" — and it's all invisible. So I built a visualizer that animates a real ApplicationContext starting up, one phase at a time.

▶ Live demo: https://dev48v.github.io/bean-lifecycle/
Source (single file, zero deps): https://github.com/dev48v/bean-lifecycle

Every phase a singleton goes through

Press "refresh context" and each bean walks the full lifecycle, the way real Spring does it:

  1. instantiate — constructor runs
  2. populate@Autowired dependencies injected
  3. aware*Aware callbacks (BeanNameAware, ApplicationContextAware, …)
  4. BeanPostProcessor — before (postProcessBeforeInitialization)
  5. @PostConstruct — your init method
  6. afterPropertiesSetInitializingBean / custom init-method
  7. BeanPostProcessor — after (postProcessAfterInitialization — where AOP proxies are created)
  8. ready — placed in the singleton cache

That step 7 is the one most people miss: AOP proxies are created by a BeanPostProcessor after initialization. It's why @Transactional/@Async work — the bean you actually get injected is a proxy wrapping your instance.

The two things the animation makes obvious

Creation follows dependencies. Beans are built bottom-up:

appConfig → dataSource → orderRepository → orderService → orderController
Enter fullscreen mode Exit fullscreen mode

A bean can't be injected until the bean it needs exists, so Spring topologically orders creation. On context.close(), it destroys in reverse order (@PreDestroyDisposableBean.destroy()) so nothing is torn down while something still depends on it.

Prototype beans are different — and dangerous. Request a prototype bean and Spring builds it fresh on demand, runs init... and then forgets about it. It never calls @PreDestroy on a prototype. Spring hands you the instance and washes its hands. If that bean holds a file handle or connection, you are responsible for closing it — a classic, quiet memory leak.

Why a visualizer

You can read "BeanPostProcessors run around initialization" and still be fuzzy on where exactly @PostConstruct sits relative to the proxy creation. Watching the phases light up in order — and watching the prototype skip its destroy callback — turns a list of terms into a model you can reason with.

One index.html, no build. If it helped, a star helps others find it: https://github.com/dev48v/bean-lifecycle

Source: dev.to

arrow_back Back to Tutorials