What is a parent-child (hierarchical) ApplicationContext in Spring, and which direction does bean visibility flow between the two levels?
answer
- Parent → child visibility only
- Child holds reference to parent, not vice-versa
- Lookup walks UP via getParentBeanFactory()
- Root MVC context + per-DispatcherServlet child
- Boot = usually flat single context
basics
~20 sA child ApplicationContext can be linked to a parent. Beans defined in the parent are visible to the child, but beans defined in the child are NOT visible to the parent. Visibility flows one way: parent-to-child.
solid answer
~40 sSpring lets you arrange ApplicationContexts into a tree: a child context holds a reference to a parent context. When you ask the child for a bean it can't find locally, the request is delegated upward to the parent, so parent beans are visible and injectable in the child. The reverse is impossible — the parent has no reference to the child and cannot see or inject child beans. This gives you a shared 'root' layer (services, repositories, datasources) plus isolated child layers that each add their own beans without polluting siblings. The classic example is Spring MVC: a root WebApplicationContext holds shared infrastructure, and each DispatcherServlet gets its own child context for web-layer beans. Plain Spring Boot apps are usually a single flat context with no hierarchy.
code
java · 12 linesAnnotationConfigApplicationContext parent =
new AnnotationConfigApplicationContext(ParentConfig.class); // defines PaymentService
AnnotationConfigApplicationContext child =
new AnnotationConfigApplicationContext();
child.setParent(parent); // link child to parent
child.register(ChildConfig.class); // defines CheckoutController
child.refresh();
child.getBean(PaymentService.class); // OK - resolved from parent
child.getBean(CheckoutController.class); // OK - local
parent.getBean(CheckoutController.class); // NoSuchBeanDefinitionException - parent can't see childgo deeper
State the one-way rule clearly: child sees parent beans, parent can't see child beans; give the MVC root-vs-servlet example.
Add that lookup delegates upward via the bean factory, and mention shared-infrastructure/isolation as the motivation.
Discuss HierarchicalBeanFactory.getParentBeanFactory delegation and where hierarchies still matter (classic MVC, Spring Cloud bootstrap) vs. flat Boot apps.
Frame trade-offs: duplicated singletons, name-hiding, getBeansOfType not spanning ancestors, and why teams usually prefer a single flat context today.
## The concept An `ApplicationContext` is Spring's IoC container — it holds bean definitions and hands out fully-wired bean instances. Spring allows contexts to be arranged into a **tree**: any context can have a single **parent** context, forming a parent-child (hierarchical) relationship. A context can have many children but at most one parent. ## Directional visibility (the core rule) Visibility is **one-directional, parent → child**: - A **child** context can see and use every bean defined in its **parent** (and any ancestor above that). - A **parent** context has **no reference to its children** and therefore **cannot** see, inject, or retrieve child beans. Why? A child stores a reference to its parent, but a parent keeps no list of its children. Resolution only ever walks *up* the tree, never down. ## How resolution works under the hood Every `ApplicationContext` wraps a `BeanFactory`. The bean factory implements `HierarchicalBeanFactory`, which exposes `getParentBeanFactory()`. When you call `getBean("x")` on the child, `AbstractBeanFactory.doGetBean` first looks in the child's own registry; if the name isn't found locally, it delegates to `getParentBeanFactory().getBean("x")`. Thus a single lookup transparently traverses the hierarchy upward. ## Why use a hierarchy? - **Sharing:** put common infrastructure (datasource, transaction manager, service beans) in a **root** context so multiple children reuse one instance. - **Isolation:** each child adds its own beans that siblings can't see, avoiding name clashes and keeping concerns separate. ## The canonical example: classic Spring MVC - A **root `WebApplicationContext`** is created by `ContextLoaderListener` and holds business/infrastructure beans. - Each **`DispatcherServlet`** builds its **own child context** for web beans (controllers, `HandlerMapping`, `ViewResolver`). Controllers can inject root services; root beans can't see controllers. ## Modern reality: Spring Boot A typical Spring Boot app runs a **single, flat context** — no hierarchy at all. Hierarchies still appear via `SpringApplicationBuilder.parent()/child()`, in classic MVC, and in Spring Cloud's bootstrap context. So candidates should know the mechanism even though everyday Boot code rarely uses it. ## Gotchas - Two contexts in a hierarchy can each hold their own singleton of the same class → duplicated instances if you're not careful. - A child bean with the same name as a parent bean **hides** the parent's version for lookups from the child. - `getBeansOfType(...)` on a context does **not** include ancestor beans by default, even though `getBean(...)` does.
- Can a context have more than one parent?No. Each context has at most one parent (one incoming reference), but a single parent can have many children — it's a tree, not a graph.
- Does a plain Spring Boot app use a context hierarchy?Usually not — it's a single flat context. Hierarchies appear only when you deliberately build one (SpringApplicationBuilder.parent/child), in classic MVC, or in Spring Cloud's bootstrap context.
saying these in an interview costs you the question
- Claiming the parent can see child beans (visibility is one-way, parent→child).
- Saying a context can have multiple parents.
- Believing every Spring Boot app is a parent-child hierarchy by default.