What is a BeanDefinition in Spring, and what information does it hold?
answer
- recipe not the dish
- class + scope + lazy + primary + values
- stored in BeanDefinitionRegistry
- define → post-process → instantiate
- one per bean regardless of source
basics
~20 sA 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 sA 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// 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
Know it's the 'recipe' for a bean holding class, scope, and dependency info, distinct from the instance.
List concrete fields (scope, lazy, primary, constructor args, property values) and that all config sources normalize into it.
Explain the define→post-process→instantiate phasing and how BeanFactoryPostProcessors mutate definitions before instantiation.
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.