skip to content

BeanDefinition & Configuration Metadata

Before any object exists, Spring holds a BeanDefinition describing it: class, scope, laziness, primary flag, autowire mode. Knowing this data model is what lets you answer how starters and libraries register beans without any annotation of yours.

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

questions

6

What is a BeanDefinition in Spring, and what information does it hold?

level: juniorimportance: must knowfreq 70%

answer

  1. recipe not the dish
  2. class + scope + lazy + primary + values
  3. stored in BeanDefinitionRegistry
  4. define → post-process → instantiate
  5. one per bean regardless of source

basics

~20 s

A BeanDefinition is Spring's recipe for a bean: it stores metadata like the class name, scope, whether it's lazy, its constructor arguments and property values, and dependencies — the container reads it to create the actual bean instance.

solid answer

~30 s

A BeanDefinition is the metadata object describing how the container should create and configure one bean — it is not the bean instance itself. It holds the bean class (or factory-method), scope (singleton/prototype), lazy-init flag, primary flag, autowire mode, constructor argument values, property values, init/destroy method names, and dependency info. Whether you use XML, @Component scanning, or @Bean methods, everything is normalized into BeanDefinition objects stored in a BeanDefinitionRegistry. During refresh, BeanFactoryPostProcessors can still mutate these definitions; only afterwards does the factory instantiate beans from them. So BeanDefinition is the design-time 'recipe', and the bean is the runtime 'dish'.

code

java · 9 lines
java
// Inspecting a registered BeanDefinition (e.g., inside a BeanFactoryPostProcessor)
ConfigurableListableBeanFactory bf = context.getBeanFactory();
BeanDefinition def = bf.getBeanDefinition("orderService");

System.out.println(def.getBeanClassName()); // e.g. com.acme.OrderService (may be null for @Bean methods)
System.out.println(def.getScope());         // "singleton"
System.out.println(def.isLazyInit());       // false
System.out.println(def.isPrimary());        // false
// No bean instance exists yet at this point — this is only the metadata.

go deeper

for a junior

Know it's the 'recipe' for a bean holding class, scope, and dependency info, distinct from the instance.

for a middle

List concrete fields (scope, lazy, primary, constructor args, property values) and that all config sources normalize into it.

for a senior

Explain the define→post-process→instantiate phasing and how BeanFactoryPostProcessors mutate definitions before instantiation.

for a principal

Discuss role hints, abstract/parent templates, factory-method vs class name, and how the metadata model underpins profiles, proxying, and tooling.

## What it is A `BeanDefinition` (interface `org.springframework.beans.factory.config.BeanDefinition`) is Spring's **in-memory description of a bean** — the configuration metadata the container needs to instantiate, configure, and manage a single bean. Crucially, it is **not the bean object itself**: it is the *recipe*, while the bean is the *cooked dish*. No matter the configuration source — XML `<bean>` elements, annotation scanning of `@Component`/`@Service`, or `@Bean` factory methods in a `@Configuration` class — Spring parses each into a `BeanDefinition` and registers it in a `BeanDefinitionRegistry` (which `DefaultListableBeanFactory` implements). Instantiation of the real beans happens **later**, during `AbstractApplicationContext.refresh()`, after all definitions are registered and post-processed. ## What a BeanDefinition holds - **`beanClassName`** — the fully-qualified class to instantiate (or `factoryBeanName` + `factoryMethodName` for `@Bean` methods). - **`scope`** — `singleton` (default), `prototype`, or a web/custom scope name. - **`lazyInit`** — if `true`, a singleton is not created eagerly at startup but on first request. - **`primary`** — marks this as the preferred candidate when multiple beans of a type exist for autowiring. - **`autowireMode`** — legacy XML autowiring mode (`no`, `byName`, `byType`, `constructor`). - **`constructorArgumentValues`** and **`propertyValues` (MutablePropertyValues)** — values/refs to inject. - **`initMethodName` / `destroyMethodName`** — lifecycle callbacks. - **`dependsOn`** — names of beans that must be created first. - **`role`** — `ROLE_APPLICATION`, `ROLE_SUPPORT`, or `ROLE_INFRASTRUCTURE` (a hint about who owns it). - **`abstract`** — if `true`, it is a template not instantiated on its own (parent for child definitions). ## Why this indirection matters Because configuration is captured as data **before** any bean is created, Spring can transform it. `BeanFactoryPostProcessor`s (e.g. `PropertySourcesPlaceholderConfigurer`) run against the raw definitions and can rewrite property values or scopes. Only after that pass does the factory begin instantiation. This two-phase model (define → post-process → instantiate) is the reason profiles, placeholders, and proxying work. ## Gotchas - A `BeanDefinition` does **not** by itself represent an instance; asking `getBean` triggers creation from it. - `getBeanClassName()` can be `null` for `@Bean`-style definitions that use a factory method instead of a direct class. - Editing a definition after the factory has been frozen/refreshed is not allowed for singletons already created. ## When to touch it directly Mostly you don't — annotations/XML suffice. You reach for the API when writing infrastructure: a `BeanFactoryPostProcessor` tweaking scopes, tooling that inspects the container, or programmatic registration via `BeanDefinitionBuilder`.

  • Is a BeanDefinition the same as the bean instance?
    No. The BeanDefinition is the metadata/recipe; the bean instance is created later by the factory from that recipe. One definition can produce many prototype instances or a single shared singleton.
  • Why does Spring normalize XML, annotations, and @Bean methods all into BeanDefinitions?
    So the container has one uniform data model to post-process and instantiate from, regardless of source. This enables BeanFactoryPostProcessors, placeholder resolution, and consistent lifecycle handling.

saying these in an interview costs you the question

  • Saying a BeanDefinition IS the bean object (it is only metadata).
  • Claiming beans are instantiated the moment their definition is registered (instantiation happens later during refresh, and lazily for lazy-init).
  • Thinking annotations bypass BeanDefinitions — @Component/@Bean are also turned into BeanDefinitions.

context

open as a page

Explain the key BeanDefinition flags — scope, lazy-init, primary, and autowire-mode — and their exact semantics and edge cases.

level: seniorimportance: must knowfreq 50%

basics

~10 s

Scope controls instance lifecycle (singleton vs prototype/web). Lazy-init delays singleton creation until first use. Primary marks the preferred autowire candidate among several. Autowire-mode is the legacy XML setting (byName/byType/constructor) for automatic dependency resolution.

open as a page

What are the main BeanDefinition implementations (RootBeanDefinition, GenericBeanDefinition, ChildBeanDefinition, AnnotatedBeanDefinition) and when is each used?

level: middleimportance: should knowfreq 45%

basics

~10 s

GenericBeanDefinition is the general-purpose, modern definition you create. RootBeanDefinition is the fully-resolved internal one the container uses at runtime. ChildBeanDefinition inherits from a parent (legacy). AnnotatedBeanDefinition adds annotation metadata for scanned/@Bean components.

open as a page

What is BeanDefinitionRegistry and how do you build/register a definition with BeanDefinitionBuilder?

level: middleimportance: should knowfreq 40%

basics

~20 s

BeanDefinitionRegistry is the container's registry of BeanDefinitions keyed by bean name — it lets you register, remove, and look up definitions. BeanDefinitionBuilder is a fluent helper to construct a BeanDefinition, then you call registry.registerBeanDefinition(name, def).

open as a page

What are merged bean definitions, and why does Spring compute a RootBeanDefinition per bean at runtime?

level: seniorimportance: should knowfreq 30%

basics

~20 s

A merged bean definition flattens a child definition together with its parent(s) into one complete RootBeanDefinition. Spring instantiates beans from this merged, fully-resolved copy so parent-inherited settings and defaults are all applied in one place.

open as a page

How can you inspect or mutate BeanDefinitions before beans are instantiated, and what are the ordering/safety rules?

level: principalimportance: should knowfreq 25%

basics

~20 s

Use a BeanFactoryPostProcessor (or BeanDefinitionRegistryPostProcessor) which Spring invokes after all definitions are loaded but before any bean is created. Through the registry/factory you read and edit definitions — change scope, property values, lazy flag, etc. — and the container instantiates from your changes.

open as a page