skip to content

Hierarchical Parent-Child ApplicationContexts

A child context can see its parent's beans but not the reverse, which is the split behind the classic root plus DispatcherServlet arrangement. Interviewers ask about it when a bean is 'not found' despite clearly existing — usually the wrong side of the hierarchy.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is a parent-child (hierarchical) ApplicationContext in Spring, and which direction does bean visibility flow between the two levels?

level: juniorimportance: must knowfreq 55%

answer

  1. Parent → child visibility only
  2. Child holds reference to parent, not vice-versa
  3. Lookup walks UP via getParentBeanFactory()
  4. Root MVC context + per-DispatcherServlet child
  5. Boot = usually flat single context

basics

~20 s

A 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 s

Spring 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 lines
java
AnnotationConfigApplicationContext 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 child

go deeper

for a junior

State the one-way rule clearly: child sees parent beans, parent can't see child beans; give the MVC root-vs-servlet example.

for a middle

Add that lookup delegates upward via the bean factory, and mention shared-infrastructure/isolation as the motivation.

for a senior

Discuss HierarchicalBeanFactory.getParentBeanFactory delegation and where hierarchies still matter (classic MVC, Spring Cloud bootstrap) vs. flat Boot apps.

for a principal

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.

context

open as a page

How does bean resolution delegate from a child context to its parent, and what happens when the child defines a bean with the same name as one in the parent?

level: middleimportance: must knowfreq 48%

basics

~20 s

When the child can't find a bean locally, it asks its parent (delegation upward). If the child defines a bean with the same name as the parent, the child's bean 'hides' the parent's for lookups made from the child — both instances can still exist independently.

open as a page

In classic Spring MVC, explain the split between the root WebApplicationContext and each DispatcherServlet's context. What goes where, and why?

level: seniorimportance: must knowfreq 45%

basics

~20 s

The root context (loaded by ContextLoaderListener) holds shared beans: services, repositories, datasource. Each DispatcherServlet creates a child context for web beans: controllers, handler mappings, view resolvers. Controllers can inject root services; root beans can't see web beans.

open as a page

What are the practical pitfalls of context hierarchies, and when would you deliberately choose a hierarchy over a single flat context?

level: seniorimportance: should knowfreq 22%

basics

~20 s

Pitfalls: duplicate singletons from overlapping scans, accidental name-shadowing, getBeansOfType not seeing ancestors, and AOP/transactions breaking on the wrong copy. Use a hierarchy only to share one root layer across several isolated children (e.g., multiple DispatcherServlets); otherwise prefer a single flat context.

open as a page

At the API level, how do you wire a parent context, and how does the bean factory implement hierarchical lookup? Cover ConfigurableApplicationContext.setParent and HierarchicalBeanFactory.getParentBeanFactory.

level: principalimportance: should knowfreq 25%

basics

~10 s

Call ConfigurableApplicationContext.setParent(parent) before refresh(). Internally the child's BeanFactory records the parent via setParentBeanFactory, and HierarchicalBeanFactory.getParentBeanFactory() exposes it. Lookups check locally, then delegate to the parent factory.

open as a page