What does InstantiationAwareBeanPostProcessor add over a plain BeanPostProcessor?
answer
- Adds instantiation-phase hooks (around constructor)
- beforeInstantiation non-null → short-circuit creation
- afterInstantiation false → skip property injection
- postProcessProperties = where @Autowired field injection happens
- Smart* adds getEarlyBeanReference for circular-dep proxies
basics
~20 sIt adds hooks that fire around instantiation itself — before the constructor runs and after, during property population — whereas a plain BeanPostProcessor only wraps the later initialization phase. It can even short-circuit creation by returning a substitute object.
solid answer
~40 sInstantiationAwareBeanPostProcessor extends BeanPostProcessor with instantiation-phase hooks. postProcessBeforeInstantiation runs before the constructor and, if it returns a non-null object, short-circuits normal creation — Spring uses that object (a common trick for supplying a bean or a target-source proxy). postProcessAfterInstantiation runs after the constructor but before property population; returning false skips Spring's field/setter injection. postProcessProperties (replacing the deprecated postProcessPropertyValues) lets you modify or inject PropertyValues — this is how AutowiredAnnotationBeanPostProcessor performs @Autowired/@Value field injection. The SmartInstantiationAwareBeanPostProcessor subinterface adds getEarlyBeanReference (used to proxy beans caught in circular references) and predictBeanType/determineCandidateConstructors. So the plain interface wraps initialization; the instantiation-aware one participates in constructor selection, instantiation short-circuiting, and injection.
code
java · 23 linesimport org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
public class GuardingIabpp implements InstantiationAwareBeanPostProcessor {
// Return non-null here to REPLACE the bean and skip normal creation entirely.
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
return null; // null = proceed with normal instantiation
}
// Return false to tell Spring NOT to inject properties (you take over).
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
return true;
}
// Inspect/augment property values before they are applied — how @Autowired works.
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
return pvs;
}
}go deeper
Not expected; awareness that a richer sub-interface exists is a bonus.
Know it adds instantiation-phase hooks and that @Autowired injection is implemented via one.
Explain all three added callbacks and the short-circuit/skip-injection semantics precisely.
Discuss SmartInstantiationAwareBeanPostProcessor (getEarlyBeanReference, determineCandidateConstructors) and its role in circular-dependency proxy consistency.
## The interface hierarchy ``` BeanPostProcessor └─ InstantiationAwareBeanPostProcessor └─ SmartInstantiationAwareBeanPostProcessor ``` A plain `BeanPostProcessor` only sees a bean **after it has been constructed and injected** (the before/after-*Initialization* callbacks). `InstantiationAwareBeanPostProcessor` (`org.springframework.beans.factory.config`) adds hooks **around instantiation and property population** — earlier and finer-grained. ## The extra callbacks 1. **`postProcessBeforeInstantiation(Class<?> beanClass, String beanName)`** — called **before the constructor**. If it returns a **non-null** object, Spring treats that as the finished bean: normal instantiation/injection/init is **skipped**, and only `postProcessAfterInitialization` still runs on it. This is the container's escape hatch for supplying a bean itself (custom proxying, target-source scenarios, mocking). 2. **`postProcessAfterInstantiation(Object bean, String beanName)`** — called **after the constructor** but **before property population**. Returning `false` tells Spring to **skip its own property injection** for this bean (you take over wiring). Returning `true` (default) continues normally. 3. **`postProcessProperties(PropertyValues pvs, Object bean, String beanName)`** — called during population to inspect/augment the `PropertyValues` before they are applied. This is where `AutowiredAnnotationBeanPostProcessor` resolves and sets `@Autowired`/`@Value`/`@Inject` fields, and `CommonAnnotationBeanPostProcessor` handles `@Resource`. It **replaced** the now-deprecated `postProcessPropertyValues`. ## SmartInstantiationAwareBeanPostProcessor An internal-leaning subinterface adding: - **`getEarlyBeanReference(Object bean, String beanName)`** — returns a reference (often a **proxy**) to expose early when a bean is caught in a **circular dependency**. This is why an AOP-proxied bean involved in a cycle is still consistently the proxy everywhere: the auto-proxy creator implements this hook. - **`determineCandidateConstructors`** — lets Spring pick which constructor(s) to use for autowiring (how `@Autowired` on a constructor is discovered). - **`predictBeanType`** — helps the container infer a bean's type before full creation (important for type matching during autowiring). ## Why it matters - Injection annotations are implemented *as* instantiation-aware BPPs — this is the mechanism behind `@Autowired`, `@Value`, `@Resource`, `@PostConstruct`. - The **before-instantiation short-circuit** is a powerful but sharp tool: return non-null and you have entirely bypassed the container's construction logic. - Proxy consistency under circular references depends on `getEarlyBeanReference`. ## Gotchas - Returning non-null from `postProcessBeforeInstantiation` skips *all* normal creation — easy to accidentally disable DI. - Returning `false` from `postProcessAfterInstantiation` disables Spring's injection; forget to wire manually and dependencies stay null. - These callbacks fire for **every** bean, including infrastructure beans; guard on type/name and keep them fast. - With Java 8+ default methods on the interface you simply implement what you need; the old `InstantiationAwareBeanPostProcessorAdapter` is deprecated in newer Spring versions.
- Which built-in BeanPostProcessor uses postProcessProperties, and for what?AutowiredAnnotationBeanPostProcessor uses it to resolve and inject @Autowired/@Value fields and methods; CommonAnnotationBeanPostProcessor similarly handles @Resource. Both are InstantiationAwareBeanPostProcessors.
- What is getEarlyBeanReference for?On SmartInstantiationAwareBeanPostProcessor, it returns an early reference (typically a proxy) exposed while a bean is still being created, so beans caught in a circular dependency receive the same proxy instance that becomes the final bean.
- What happens if postProcessBeforeInstantiation returns a non-null object?Spring uses that object as the bean, skipping normal instantiation, property population, and initialization callbacks; only postProcessAfterInitialization still runs on it.
saying these in an interview costs you the question
- Thinking InstantiationAwareBeanPostProcessor runs at the same time as the plain init callbacks
- Believing @Autowired field injection is 'magic' rather than done by an instantiation-aware BPP
- Confusing postProcessBeforeInstantiation (skips creation) with postProcessBeforeInitialization (wraps init)