If a bean uses @PostConstruct, implements InitializingBean, and also declares an @Bean initMethod, in what order do the init callbacks run?
answer
- Init: annotation → interface → declared method
- @PostConstruct → afterPropertiesSet → initMethod
- Destroy mirrors: @PreDestroy → destroy() → destroyMethod
- Same method twice = called once
- @PostConstruct fires in postProcessBeforeInitialization
basics
~10 sFirst @PostConstruct, then InitializingBean.afterPropertiesSet(), then the @Bean initMethod. Destruction mirrors it: @PreDestroy, then DisposableBean.destroy(), then the @Bean destroyMethod.
solid answer
~30 sSpring runs all three init hooks in a fixed order. First the JSR-250 @PostConstruct method (invoked by CommonAnnotationBeanPostProcessor, a BeanPostProcessor that runs during postProcessBeforeInitialization). Then InitializingBean.afterPropertiesSet(). Then the custom init method named via @Bean(initMethod) or XML init-method. Destruction is the mirror image: @PreDestroy first, then DisposableBean.destroy(), then the configured destroyMethod. The mnemonic is annotation → interface → declared-method for both directions. A subtle detail: if the same physical method is referenced by more than one mechanism (say it's both @PostConstruct-annotated and named as initMethod), Spring recognizes the duplicate and invokes it only once rather than twice.
code
java · 16 linesimport jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.InitializingBean;
class Ordered implements InitializingBean {
@PostConstruct
void a() { System.out.println("1: @PostConstruct"); }
@Override
public void afterPropertiesSet() { System.out.println("2: afterPropertiesSet"); }
void c() { System.out.println("3: initMethod"); }
}
// @Bean(initMethod = "c")
// Ordered ordered() { return new Ordered(); }
// Prints 1, then 2, then 3.go deeper
Just remember the sequence: @PostConstruct, then afterPropertiesSet, then initMethod.
State the order confidently for both init and destroy and know the de-dup rule.
Tie the order to the post-processor vs invokeInitMethods split and the surrounding creation flow.
Discuss where AOP proxying sits, intra- vs inter-bean ordering, and why layering exists.
When a single bean wires up **all three** initialization mechanisms, Spring executes them in a **deterministic, documented order**. Understanding *why* requires knowing that `@PostConstruct`/`@PreDestroy` are handled by a `BeanPostProcessor` (the `CommonAnnotationBeanPostProcessor`, technically its superclass `InitDestroyAnnotationBeanPostProcessor`), while the interface and declared-method callbacks are handled by the core bean factory's `invokeInitMethods`. **Initialization order:** 1. **`@PostConstruct`** — runs inside `postProcessBeforeInitialization`, i.e. *before* the factory's own init-method invocation. 2. **`InitializingBean.afterPropertiesSet()`** — the factory calls this first inside `invokeInitMethods`. 3. **Custom init method** — `@Bean(initMethod = "...")` (or XML `init-method`), invoked by reflection immediately after `afterPropertiesSet()`. **Destruction order (the mirror):** 1. **`@PreDestroy`** — via the same post-processor's destroy path. 2. **`DisposableBean.destroy()`**. 3. **Custom destroy method** — `@Bean(destroyMethod = "...")` / XML `destroy-method`. So the rule for both directions is: **annotation → interface → declared method**. **Where this order sits in the overall bean creation flow:** constructor → dependency injection (setters/fields) → `BeanNameAware`/`BeanFactoryAware`/`ApplicationContextAware` etc. `set*` methods → `BeanPostProcessor.postProcessBeforeInitialization` (this is where `@PostConstruct` fires) → `afterPropertiesSet()` → custom init method → `BeanPostProcessor.postProcessAfterInitialization` (where AOP proxies are typically created) → bean ready. On shutdown the destroy order above runs in reverse relative to init. **De-duplication gotcha:** If you point two mechanisms at the *same* method — e.g. a method named `init()` that is both `@PostConstruct`-annotated and declared as `@Bean(initMethod = "init")` — Spring detects the collision and calls it **only once**, not twice. This prevents accidental double-initialization when developers combine styles. **Cross-bean ordering is different:** This ordering is *within one bean*. Across beans, init callbacks respect the dependency graph — a bean's dependencies are fully initialized (including their `@PostConstruct`) before the dependent bean's init callbacks run. You can nudge inter-bean ordering with `@DependsOn`, but you cannot reorder the three intra-bean hooks. **Why it matters:** Rarely do you use all three, but interviewers use this to check whether you understand that these mechanisms are *layered*, not mutually exclusive, and that the container has a single well-defined sequence. In practice, pick one mechanism per concern to keep the sequence obvious.
- What happens if the same method is both @PostConstruct-annotated and named as the @Bean initMethod?Spring recognizes it's the same method and invokes it only once, avoiding a double call.
- At what stage of bean creation does @PostConstruct actually fire relative to AOP proxy creation?@PostConstruct runs during postProcessBeforeInitialization; AOP proxies are usually created in postProcessAfterInitialization, so @PostConstruct executes on the raw target before proxying.
saying these in an interview costs you the question
- Saying afterPropertiesSet() runs before @PostConstruct
- Claiming the order is undefined or depends on registration order
- Believing the same method gets called twice when wired by two mechanisms