Question 6 · Section 5

What is Bean Lifecycle?

Three caches for resolving circular dependencies:

Language versions: English Russian Ukrainian

Junior Level

Bean Lifecycle is all the stages of a bean from creation to destruction.

Why know lifecycle: (1) initialize resources at the right moment, (2) understand why @Transactional does not work from @PostConstruct, (3) properly clean up resources, (4) resolve circular dependencies.

Simple analogy: A person’s life: birth -> growing up -> work -> retirement.

Main stages:

1. Creation (constructor)
2. Dependency injection
3. Initialization (@PostConstruct)
4. Working (ready to use)
5. Destruction (@PreDestroy)

In Spring 6 / Boot 3: use jakarta.annotation.PostConstruct instead of javax.annotation.PostConstruct.

@Service
public class MyBean {

    public MyBean() {
        // 1. Creation
    }

    @PostConstruct
    public void init() {
        // 3. Initialization
    }

    @PreDestroy
    public void cleanup() {
        // 5. Destruction
    }
}

Middle Level

Lifecycle Phases

1. BeanDefinition -> meta-information
2. Instantiation -> constructor
3. Populate Properties -> @Autowired
4. Aware Interfaces -> setBeanName, setBeanFactory
5. @PostConstruct -> initialization
6. Ready -> bean is ready
7. @PreDestroy -> cleanup

Singleton vs Prototype

Stage Singleton Prototype
Creation Once Every time on request
Initialization Yes Yes
Destruction Yes NO NOT called!
// Prototype: you must clean up resources yourself!
PrototypeBean bean = context.getBean(PrototypeBean.class);
try {
    // usage
} finally {
    bean.cleanup();  // Manually!
}

SmartLifecycle

// For starting/stopping components
@Component
public class MyService implements SmartLifecycle {
    public void start() { /* Start after all beans are initialized */ }
    public void stop() { /* Stop on shutdown */ }
    public boolean isRunning() { return running; }
    public int getPhase() { return 0; }  // Startup order
}

Senior Level

When NOT to Use @PostConstruct

  1. Heavy initialization - blocks the entire context startup. Use SmartLifecycle or @EventListener(ContextRefreshedEvent)
  2. Calling @Transactional methods - proxy does not exist yet, transaction does not work
  3. Operations with retry - if initialization can fail (no DB connection), use SmartLifecycle with retries

Three-Level Cache and Cycles

Three caches for resolving circular dependencies:

  1. singletonObjects - ready beans (fully initialized)
  2. earlySingletonObjects - created but not initialized (for breaking cycles)
  3. singletonFactories - factories producing early references
DefaultListableBeanFactory caches:
  1. singletonObjects -> ready beans
  2. earlySingletonObjects -> created but not initialized
  3. singletonFactories -> factories for getting early reference

-> Resolves cycles for Field/Setter Injection
-> Constructor Injection cannot use cache 3

Proxy Creation Point

BPP.postProcessAfterInitialization():
  -> This is where AOP Proxies are created
  -> Bean is replaced by Proxy in container

@PostConstruct is called BEFORE proxy!
  -> Calling @Transactional method from @PostConstruct will NOT work
  -> Solution: ApplicationListener<ContextRefreshedEvent>

BPP Ordering

// BPP order matters!
@Order(1)
public class FirstBPP implements BeanPostProcessor { }

@Order(2)
public class SecondBPP implements BeanPostProcessor { }

-> FirstBPP runs earlier

Production Experience

Real scenario: @PostConstruct + @Transactional

@PostConstruct
public void init() {
    loadData();  // @Transactional -> does NOT work!
}

// Reason: proxy does not exist yet
// Solution:
@EventListener(ContextRefreshedEvent.class)
public void init() {
    loadData();  // Now proxy exists -> transaction works
}

Best Practices

  1. @PostConstruct -> validation, initialization
  2. @PreDestroy -> resource cleanup
  3. Prototype -> clean up resources yourself
  4. SmartLifecycle -> startup order
  5. @PostConstruct -> proxy does not exist yet!
  6. BPP order -> manage via @Order

Summary for Senior

  • Instantiation != Initialization
  • Three-level cache -> cycle resolution
  • Proxy created AFTER @PostConstruct
  • Prototype -> @PreDestroy NOT called
  • SmartLifecycle -> start/stop components
  • ContextRefreshedEvent -> when everything is ready

Interview Cheat Sheet

Must know:

  • Bean Lifecycle: creation -> dependency injection -> initialization (@PostConstruct) -> ready -> destruction (@PreDestroy)
  • Lifecycle is needed for: resource initialization, understanding why @Transactional does not work from @PostConstruct, resource cleanup, resolving cycles
  • Singleton: all stages 1-12, @PreDestroy called on context shutdown
  • Prototype: only creation and initialization, @PreDestroy NOT called - clean up manually
  • Three-level cache (singletonObjects, earlySingletonObjects, singletonFactories) resolves circular dependencies
  • Proxy created AFTER @PostConstruct - calling @Transactional method from @PostConstruct will not work
  • SmartLifecycle - for starting/stopping components with order (getPhase())
  • In Spring 6 / Boot 3: jakarta.annotation.PostConstruct instead of javax.annotation

Common follow-up questions:

  • Why doesn’t @Transactional work from @PostConstruct? Proxy is created after @PostConstruct, call goes to the original object.
  • How to solve the transaction problem during initialization? @EventListener(ContextRefreshedEvent.class) - all proxies already exist.
  • Why doesn’t Prototype call @PreDestroy? Spring does not track prototype bean destruction - call cleanup manually.
  • What is the three-level cache? Cache of ready beans, early references, and factories - resolves cycles for Field/Setter Injection.

Red flags (DO NOT say):

  • @PostConstruct is the place for heavy initialization” (blocks context startup, use SmartLifecycle)
  • “Prototype beans are cleaned up automatically” (@PreDestroy NOT called for Prototype)
  • “All scopes work the same with lifecycle” (Prototype skips destruction stages)
  • @PostConstruct and initialization are the same thing” (Instantiation != Initialization)

Related topics:

  • [[07. What are the Bean Lifecycle stages]]
  • [[08. What is BeanPostProcessor]]
  • [[09. What do PostConstruct and PreDestroy methods do]]
  • [[04. What is a Bean in Spring]]
  • [[10. What is Bean scope]]