Sobes.tech
Middle

What is the lifecycle of an object created in Spring?

sobes.tech AI

Answer from AI

  1. Instantiate: Spring creates an instance of the object.
  2. Populate Properties: Dependencies (fields annotated with @Autowired, @Value, etc.) are injected via setters or fields.
  3. Aware Interfaces: If the bean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, or other Aware interfaces, Spring calls the corresponding methods (setBeanName, setBeanFactory, setApplicationContext, etc.), passing the context.
  4. BeanPostProcessors (pre-initialization): Before calling initialization methods, postProcessBeforeInitialization of registered BeanPostProcessors is invoked.
  5. Initializing Bean:
    • If the bean implements InitializingBean, its afterPropertiesSet() method is called.
    • If an initialization method is specified via @Bean(initMethod="...") or init-method in XML, that method is called.
  6. BeanPostProcessors (post-initialization): After initialization, postProcessAfterInitialization of registered BeanPostProcessors is invoked. Proxy objects are often created at this stage (e.g., for transactions or security).
  7. Ready to Use: The object is considered fully configured and ready for use.
  8. Destroy:
    • If the bean implements DisposableBean, its destroy() method is called.
    • If a destroy method is specified via @Bean(destroyMethod="...") or destroy-method in XML, that method is called.
    • The method annotated with @PreDestroy is invoked.
  9. Cleanup: Spring removes the bean from the context.
// Example of a bean participating in the lifecycle
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.BeanNameAware;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class MySpringBean implements InitializingBean, DisposableBean, BeanNameAware {

    private String beanName;

    // 2. Populate Properties (via setter)
    private Dependency requiredDependency;

    public void setRequiredDependency(Dependency requiredDependency) {
        System.out.println("2. Setting dependency");
        this.requiredDependency = requiredDependency;
    }

    // 3. Aware Interfaces
    @Override
    public void setBeanName(String name) {
        System.out.println("3. Setting bean name: " + name);
        this.beanName = name;
    }

    // 5. Initializing Bean (from InitializingBean)
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("5. InitializingBean afterPropertiesSet() called");
        // Initialization logic
    }

    // 5. Initializing Bean (from @PostConstruct)
    @PostConstruct
    public void postConstructMethod() {
        System.out.println("5. @PostConstruct method called");
        // Initialization logic
    }

    // 5. Initializing Bean (user-defined initMethod)
    public void customInitMethod() {
        System.out.println("5. Custom init method called");
        // Initialization logic
    }

    // 7. Ready to Use
    public void doSomething() {
        System.out.println("7. Bean is ready and doing something");
    }

    // 8. Destroy (from DisposableBean)
    @Override
    public void destroy() throws Exception {
        System.out.println("8. DisposableBean destroy() called");
        // Cleanup logic
    }

    // 8. Destroy (from @PreDestroy)
    @PreDestroy
    public void preDestroyMethod() {
        System.out.println("8. @PreDestroy method called");
        // Cleanup logic
    }

    // 8. Destroy (user-defined destroyMethod)
    public void customDestroyMethod() {
        System.out.println("8. Custom destroy method called");
        // Cleanup logic
    }

    // Inner class for dependency example
    public static class Dependency {
        // ...
    }
}