Spring Bean Life Cycle in Spring Boot: Phases and Order

The Spring bean life cycle runs from instantiation and dependency injection to the init callbacks and, at shutdown, the destroy callbacks. See the exact callback order in a Spring Boot app with real output, plus the Aware interfaces, XML config and the shutdown hook.

Spring bean life cycle diagram in two columns. Startup steps 1 to 9 on the left are Constructor, Dependency injection, BeanNameAware.setBeanName(), ApplicationContextAware.setApplicationContext(), BeanPostProcessor before initialization, @PostConstruct method, InitializingBean.afterPropertiesSet(), custom init method and BeanPostProcessor after initialization. An arrow leads to step 10, bean is ready and in use. After context.close() or the JVM shutdown hook come step 11 @PreDestroy method, step 12 DisposableBean.destroy() and step 13 custom destroy method. A note says prototype beans get steps 1 to 9 only.

The Spring bean life cycle is the fixed sequence of steps that the Spring container runs for every bean, from creating the object and injecting its dependencies to calling its cleanup code when the container closes. We can hook our own code into two points of that sequence, namely right after the bean is ready (initialization callbacks) and right before Spring removes it (destruction callbacks).

We use these callbacks for setup and cleanup work that the constructor cannot do, such as checking injected dependencies, loading a cache at startup, starting a scheduler, or closing connections and files at shutdown.

The following example is a Spring Boot 4.1.1 component with one callback of each kind. In a Spring Boot application, both annotations work with no extra setup.

@Component
class PlaylistCache {

  @PostConstruct
  void load() {
    System.out.println("PlaylistCache @PostConstruct");   // runs once, after dependency injection
  }

  @PreDestroy
  void clear() {
    System.out.println("PlaylistCache @PreDestroy");      // runs once, when the context closes
  }
}

Notice that we never call load() or clear() ourselves. Spring calls load() during startup, and it calls clear() when the application context closes, which in Spring Boot happens from a JVM shutdown hook.

Next, we go through all 13 steps of the life cycle with real output, and the four ways to add callbacks, namely annotations, interfaces, custom init and destroy methods, and Aware interfaces. After that, we cover the shutdown hook, prototype beans and the questions that come up most often.

1. What is Lifecycle of a Bean in Spring?

The lifecycle of a bean in the Spring Framework refers to the series of steps and methods that a bean goes through from its instantiation to its eventual destruction.

The Spring container (an ApplicationContext, which builds on the BeanFactory) runs these steps. It creates, configures and destroys beans according to the bean scope (singleton, prototype, etc.). For a singleton bean, the steps run in the order shown in the diagram.

Spring bean life cycle diagram in two columns. Startup steps 1 to 9 on the left are Constructor, Dependency injection, BeanNameAware.setBeanName(), ApplicationContextAware.setApplicationContext(), BeanPostProcessor before initialization, @PostConstruct method, InitializingBean.afterPropertiesSet(), custom init method and BeanPostProcessor after initialization. An arrow leads to step 10, bean is ready and in use. After context.close() or the JVM shutdown hook come step 11 @PreDestroy method, step 12 DisposableBean.destroy() and step 13 custom destroy method. A note says prototype beans get steps 1 to 9 only.
Spring creates and initializes the bean in steps 1 to 9, and it runs the destruction callbacks 11 to 13 only when the context closes.

We can group the 13 steps into four phases, and each phase has its own hooks for our code.

PhaseStepsWhat happensOur hook
Creation1-2Spring calls the constructor and injects the dependencies.constructor, setters
Aware callbacks3-4Spring passes infrastructure objects such as the bean name.Aware interfaces
Initialization5-9Spring runs the post processors and the init callbacks.@PostConstruct, afterPropertiesSet(), init method, BeanPostProcessor
Destruction11-13Spring runs the destroy callbacks when the context closes.@PreDestroy, destroy(), destroy method

A BeanPostProcessor is a special bean that Spring calls for every other bean, once before and once after the init callbacks. Spring uses its own post processors for many features, for example it calls @PostConstruct methods from one of them, and it creates AOP proxies in the “after initialization” step.

2. Bean Lifecycle Callback Methods

Spring lets a bean run its own code at two points of the life cycle, so the callback methods fall into two groups.

  • Post-initialization callback methods run once the bean is created and all dependencies are injected.
  • Pre-destruction callback methods run when the container closes.

In Spring, the initialization life-cycle callback methods will be called on objects regardless of bean scope, while for beans with prototype scope, the destruction life-cycle callback methods will not be called.

It’s the responsibility of the application to manage the destruction and cleanup of prototype beans, as Spring does not keep a reference to prototype beans for automatic destruction. We cover the cleanup options for prototype beans in section 10.2.

2.1. Post-Initialization Callbacks

Most often, but not limited to, the initialization callbacks are used to perform the dependency checks that are not possible in the constructor. With setter or field injection, the dependencies are still null inside the constructor, and Spring sets them before the init callback runs. Other use cases are loading a cache and starting a scheduler.

For example, a music app keeps the 500 most played songs in memory. The PlaylistService bean loads them from the database in its init callback, so the first request finds the cache full.

The post-initialization callback method cannot accept any arguments. It can return any type, and Spring ignores the returned value. A @PostConstruct method with a parameter makes the context fail at startup with IllegalStateException: Lifecycle annotation requires a no-arg method.

We can even define all initialization mechanisms on the same bean instance. It is allowed in Spring. In this case, Spring invokes the callbacks in the following order.

  1. Method annotated with @PostConstruct
  2. Method InitializingBean.afterPropertiesSet()
  3. Method specified in the @Bean(initMethod = “…”) definition or the XML init-method attribute

Spring runs the init callbacks inside the container’s singleton creation lock. So we keep them short, and we move slow work, such as warming a large cache over the network, to a ContextRefreshedEvent listener or to SmartInitializingSingleton.afterSingletonsInstantiated().

2.2. Pre-destruction Callbacks

When the application shuts down, Spring calls the ConfigurableBeanFactory.destroySingletons()) method which provides us a chance to clean up any resources that the beans might be holding open, so the application shuts down gracefully. When the destroySingletons() is called, the beans get the notifications via pre-destruction callback methods (similar to post-initialization callbacks).

The destruction callback is often used in conjunction with the initialization callback. In many cases, we create and configure a resource in the initialization callback and release the resource in the destruction callback.

The method name destroySingletons() shows that beans with other scopes than singleton do not have their life cycle fully managed by Spring.

As with the case of bean creation, the order of method invocations in case of multiple bean destruction callbacks is as follows.

  1. Method annotated with @PreDestroy
  2. Method DisposableBean.destroy()
  3. Method specified in the @Bean(destroyMethod = “…”) definition or the XML destroy-method attribute

3. Spring Bean Life Cycle Example With All 13 Steps

The order of the steps is easier to remember once we see it printed. So we put every callback on one bean and print a numbered line from each of them.

The following example is a PlaylistService bean that gets a SongStore dependency through a setter and loads the songs at startup. The bean implements BeanNameAware, ApplicationContextAware, InitializingBean and DisposableBean, and it also has @PostConstruct and @PreDestroy methods. The example uses Spring Framework 7.0.9 without Spring Boot, jakarta.annotation-api 3.0.0 and Java 25, and the complete code is in the spring-core repository.

public class PlaylistService implements BeanNameAware, ApplicationContextAware,
    InitializingBean, DisposableBean {

  private SongStore songStore;
  private final List<String> songs = new ArrayList<>();

  public PlaylistService() {
    System.out.println("1. Constructor");
  }

  @Autowired
  public void setSongStore(SongStore songStore) {
    this.songStore = songStore;
    System.out.println("2. Setter injection: setSongStore()");
  }

  @Override
  public void setBeanName(String name) {
    System.out.println("3. BeanNameAware.setBeanName(): " + name);
  }

  @Override
  public void setApplicationContext(ApplicationContext context) {
    System.out.println("4. ApplicationContextAware.setApplicationContext()");
  }

  @PostConstruct
  public void checkStore() {
    if (songStore == null) {
      throw new IllegalStateException("songStore is required");
    }
    System.out.println("6. @PostConstruct checkStore()");
  }

  @Override
  public void afterPropertiesSet() {
    System.out.println("7. InitializingBean.afterPropertiesSet()");
  }

  public void loadSongs() {
    songs.addAll(songStore.findAll());
    System.out.println("8. Init method loadSongs(): " + songs.size() + " songs");
  }

  @PreDestroy
  public void saveState() {
    System.out.println("11. @PreDestroy saveState()");
  }

  @Override
  public void destroy() {
    System.out.println("12. DisposableBean.destroy()");
  }

  public void clearSongs() {
    songs.clear();
    System.out.println("13. Destroy method clearSongs()");
  }
}

The configuration class registers PlaylistService with the names of its init and destroy methods. It also registers a small LoggingPostProcessor, which prints steps 5 and 9 for PlaylistService only. We declare the post processor @Bean method as static, because Spring must create post processors before all other beans.

@Configuration
public class AppConfig {

  @Bean
  static LoggingPostProcessor loggingPostProcessor() {
    return new LoggingPostProcessor();
  }

  @Bean
  SongStore songStore() {
    return new SongStore();
  }

  @Bean(initMethod = "loadSongs", destroyMethod = "clearSongs")
  PlaylistService playlistService() {
    return new PlaylistService();
  }
}

public class LoggingPostProcessor implements BeanPostProcessor {

  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) {
    if (bean instanceof PlaylistService) {
      System.out.println("5. BeanPostProcessor.postProcessBeforeInitialization()");
    }
    return bean;
  }

  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) {
    if (bean instanceof PlaylistService) {
      System.out.println("9. BeanPostProcessor.postProcessAfterInitialization()");
    }
    return bean;
  }
}

The main() method opens the context in a try-with-resources block. The block closes the context at its end, even when the code inside throws an exception, so the destroy callbacks always run.

try (var context = new AnnotationConfigApplicationContext(AppConfig.class)) {
  PlaylistService service = context.getBean(PlaylistService.class);
  System.out.println("10. Bean in use: " + service.getSongs());
}

The console shows all 13 steps in the order of the diagram in section 1.

1. Constructor
2. Setter injection: setSongStore()
3. BeanNameAware.setBeanName(): playlistService
4. ApplicationContextAware.setApplicationContext()
5. BeanPostProcessor.postProcessBeforeInitialization()
6. @PostConstruct checkStore()
7. InitializingBean.afterPropertiesSet()
8. Init method loadSongs(): 3 songs
9. BeanPostProcessor.postProcessAfterInitialization()
10. Bean in use: [Intro, Blue, Night Drive]
11. @PreDestroy saveState()
12. DisposableBean.destroy()
13. Destroy method clearSongs()

We can see that the dependency is already injected in step 2, so the null check in checkStore() passes. In a real bean, we pick one init mechanism and one destroy mechanism, because three callbacks for the same job make the code harder to follow.

4. Implementing the InitializingBean and DisposableBean Interfaces

The org.springframework.beans.factory.InitializingBean interface allows a bean to perform initialization work after all necessary properties on the bean have been set by the container. The InitializingBean interface specifies a single method afterPropertiesSet() which Spring calls after the bean’s properties have been set.

public class PlaylistService implements InitializingBean {

  @Override
  public void afterPropertiesSet() {
    System.out.println("7. InitializingBean.afterPropertiesSet()");
  }
}

Similarly, implementing the org.springframework.beans.factory.DisposableBean interface allows a bean to get a callback during bean destruction, such as when the application context is closed. The DisposableBean interface specifies a single method destroy(), which Spring calls when it destroys the bean.

public class PlaylistService implements DisposableBean {

  @Override
  public void destroy() {
    System.out.println("12. DisposableBean.destroy()");
  }
}

The Spring team recommends not to use InitializingBean, because it couples our class to Spring interfaces. The annotations from section 7 and the custom methods from section 6 do the same job without that coupling. The interfaces still make sense in framework code, and we see them in many Spring classes.

5. Aware Interfaces to Add Specific Behavior

Spring offers a range of interfaces that allow the beans to tell the container that they require a particular infrastructure dependency. Each of these Aware interfaces requires us to implement one setter method, and Spring calls it before the init callbacks, as steps 3 and 4 of the example show.

Some commonly used Aware interfaces are listed in the table.

Aware interfaceMethod to OverridePurpose
ApplicationContextAwaresetApplicationContext()Sets the ApplicationContext that the bean runs in.
ApplicationEventPublisherAwaresetApplicationEventPublisher()Sets the ApplicationEventPublisher that the bean runs in.
BeanNameAwaresetBeanName()Sets the name of the bean in the bean factory.
LoadTimeWeaverAwaresetLoadTimeWeaver()Sets the LoadTimeWeaver of this object’s containing ApplicationContext.
MessageSourceAwaresetMessageSource()Sets the MessageSource that this bean runs in.
NotificationPublisherAwaresetNotificationPublisher()Sets the NotificationPublisher instance for the current managed resource instance.
ResourceLoaderAwaresetResourceLoader()Sets the ResourceLoader that this object runs in.
ServletContextAwaresetServletContext()Sets the ServletContext that this object runs in.

A simple Java bean definition shows how to use the Aware interfaces. The bean keeps the ApplicationContext in a field and can use it in other methods.

public class DemoBean implements ApplicationContextAware {

  private ApplicationContext ctx;

  @Override
  public void setApplicationContext(ApplicationContext ctx) throws BeansException {
    this.ctx = ctx;
  }

  //Use the context in other bean methods
}

In application code, we can inject most of these objects with @Autowired or constructor injection instead, e.g. ApplicationContext, ApplicationEventPublisher and ResourceLoader. The Aware interfaces remain the way to get the bean’s own name.

6. Custom init() and destroy() Methods

Custom init and destroy methods are plain methods with any name, so the bean class does not depend on Spring at all. We can add them in three ways.

  • Local definitions apply to a single bean.
  • Global definitions apply to all beans defined in the whole XML file.
  • Inferred destroy methods are found by Spring on its own, when the bean has a public close() or shutdown() method.

6.1. Bean-specific Init and Destroy Methods

In Java configuration, we pass the method names to the @Bean annotation.

@Bean(initMethod = "loadSongs", destroyMethod = "clearSongs")
PlaylistService playlistService() {
  return new PlaylistService();
}

The local init and destroy methods can be configured for a specific bean with the init-method and destroy-method attributes in XML configuration.

<bean id="playlistService" class="com.howtodoinjava.core.lifecycle.PlaylistService"
      init-method="loadSongs" destroy-method="clearSongs">
  <property name="songStore" ref="songStore"/>
</bean>

The init and destroy methods are defined in the bean as ordinary public methods with no parameters.

public void loadSongs() {
  songs.addAll(songStore.findAll());
  System.out.println("8. Init method loadSongs(): " + songs.size() + " songs");
}

public void clearSongs() {
  songs.clear();
  System.out.println("13. Destroy method clearSongs()");
}

When the method name has a typo, such as initMethod = “loadSong”, Spring stops at startup with BeanDefinitionValidationException: Could not find an init method named ‘loadSong’ on bean with name ‘playlistService’, so the typo shows up on the first run.

6.2. Global-scoped Init and Destroy Methods

We can define the init and destroy methods at the global level as well. The container invokes the global init and destroy methods for all bean definitions in the XML file using the attributes default-init-method and default-destroy-method of the beans element.

Global overrides are helpful when we have a pattern of defining common method names such as init() and cleanup() for all the beans consistently. This feature helps us not to duplicate the init and destroy methods for all beans, separately.

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
         https://www.springframework.org/schema/beans/spring-beans.xsd"
       default-init-method="init" default-destroy-method="cleanup">

  <bean id="reportJob" class="com.howtodoinjava.core.lifecycle.ReportJob"/>
</beans>

The beans that want the callbacks declare methods with these names. A bean without an init() or cleanup() method is skipped, with no error, so playlistService in the same file is not affected.

public class ReportJob {
  public void init() {
    System.out.println("ReportJob.init()");
  }
  public void cleanup() {
    System.out.println("ReportJob.cleanup()");
  }
}

An XML file without Java config turns off annotation processing. With the full lifecycle-beans.xml file, Spring calls init(), cleanup(), afterPropertiesSet() and the XML init and destroy methods, but not @PostConstruct or @PreDestroy. To turn on the annotations in an XML file, we add the context:annotation-config element.

6.3. Inferred close() and shutdown() Methods

For @Bean methods, Spring looks for a public close() or shutdown() method on the bean and calls it as the destroy method. This is the default, so beans that implement AutoCloseable, such as a DataSource or a file reader, get closed with no configuration.

public class SongFileReader implements AutoCloseable {

  @Override
  public void close() {
    System.out.println("SongFileReader.close()");   // called when the context closes
  }
}

@Bean
SongFileReader songFileReader() {
  return new SongFileReader();
}

In XML, we get the same behavior with destroy-method=”(inferred)”. When a bean has a close() method that Spring must not call, for example because another component owns the resource, we turn off the inference with @Bean(destroyMethod = “”).

7. @PostConstruct and @PreDestroy Annotations

The JSR-250 annotations @PostConstruct and @PreDestroy are the recommended way to add life cycle callbacks, because the bean class does not depend on Spring interfaces.

  • A method annotated with @PostConstruct is invoked after Spring has created the bean and injected all its dependencies, and before Spring hands the bean to other beans.
  • A method annotated with @PreDestroy is invoked when Spring is about to destroy the bean, which happens when the container closes.

Since Spring Framework 6, both annotations come from the jakarta.annotation package. Spring Boot’s spring-boot-starter already includes jakarta.annotation-api, whereas a Spring application without Spring Boot needs the dependency in its pom.xml.

<dependency>
  <groupId>jakarta.annotation</groupId>
  <artifactId>jakarta.annotation-api</artifactId>
  <version>3.0.0</version>
</dependency>

The ShoppingCart bean uses both annotations. We use the same class as a prototype bean in section 10.2.

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;

public class ShoppingCart {

  @PostConstruct
  public void init() {
    System.out.println("ShoppingCart @PostConstruct");
  }

  @PreDestroy
  public void cleanup() {
    System.out.println("ShoppingCart @PreDestroy");
  }
}

Old code that imports javax.annotation.PostConstruct does not work in Spring Framework 7. Spring 7 never calls a method with the javax annotation, and it logs no warning. When we migrate an app from Spring Boot 2.x, we replace every javax.annotation import with jakarta.annotation.

8. Registering a Shutdown Hook is Necessary

When we run the demo programs from the previous sections, we expect the program to print the messages written in post-init and pre-destroy callback methods. Let’s try it with a context that we never close.

var context = new AnnotationConfigApplicationContext(AppConfig.class);

The program output prints only the init messages, steps 1 to 9. The destroy callback messages are not printed.

1. Constructor
...
8. Init method loadSongs(): 3 songs
9. BeanPostProcessor.postProcessAfterInitialization()

This is because, to call the pre-destroy callbacks, we must call the close() method of the context before the application stops. But when an application can be closed, stopped or killed in several ways, it becomes harder to place the close() call.

Java allows us to register a shutdown hook, which is a thread that is executed before the application shuts down.

To take advantage of this mechanism, we must invoke the registerShutdownHook() method of ConfigurableApplicationContext anytime before the application is stopped. Let’s try this in our demo program.

var context = new AnnotationConfigApplicationContext(AppConfig.class);
context.registerShutdownHook();

The program output prints all the init and destroy messages this time, which is the expected behavior.

1. Constructor
...
9. BeanPostProcessor.postProcessAfterInitialization()
11. @PreDestroy saveState()
12. DisposableBean.destroy()
13. Destroy method clearSongs()

The JVM runs shutdown hooks on a normal exit, on Ctrl+C and on a kill PID (SIGTERM). The JVM does not run them on kill -9 or a power loss, so no destroy callback can be a replacement for data that must be saved at once.

8.1. Bean Life Cycle in Spring Boot

In a Spring Boot application, we don’t register the hook ourselves. Every SpringApplication registers a JVM shutdown hook by default, so the context closes and the destroy callbacks run when the app stops. The life cycle steps themselves are the same as in Spring Framework, because Spring Boot uses the same container.

The following example is the PlaylistCache component from the intro, started with SpringApplication.run() in Spring Boot 4.1.1. The main() method prints a line after run() returns.

@SpringBootApplication
public class BootApp {
  public static void main(String[] args) {
    SpringApplication.run(BootApp.class, args);
    System.out.println("main() returned");
  }
}

The app has no web server, so the JVM exits after main() returns, and the shutdown hook closes the context.

PlaylistCache @PostConstruct
main() returned
PlaylistCache @PreDestroy

The property spring.main.register-shutdown-hook=false turns the hook off. With that property, the same app prints only the first two lines, so we set it only when our own code closes the context.

9. Which Life Cycle Callback Should We Use?

All four ways run at a known point of the life cycle, so the choice depends on who owns the bean class and how the bean is registered.

WayCoupled to SpringWorks for classes we cannot changeTypical use
@PostConstruct / @PreDestroyno (Jakarta annotations)noour own @Component and @Service classes
@Bean(initMethod, destroyMethod)noyesthird-party classes registered in a @Configuration class
Inferred close() / shutdown()noyesAutoCloseable resources such as pools and clients
InitializingBean / DisposableBeanyesnoframework and library code

For our own @Component classes, the annotations are the simplest choice. For a third-party class, such as a client from a library, we cannot add annotations, so we register it with a @Bean method and name its init and destroy methods there.

10. Spring Bean Life Cycle FAQs

10.1. What Is the Difference Between the Constructor and @PostConstruct?

The constructor runs before Spring injects setter and field dependencies, whereas @PostConstruct runs after all dependencies are injected. So code that uses an @Autowired field belongs in @PostConstruct. With constructor injection, the dependencies are available in the constructor too, so either place works for code that needs only those dependencies.

10.2. Why Is @PreDestroy Not Called for Prototype Beans?

Spring creates a prototype bean, runs its init callbacks and hands it over, but it keeps no reference to it. So Spring has nothing to destroy when the context closes. When a prototype bean holds a resource, our code destroys it by calling destroyBean(), which runs the @PreDestroy method and DisposableBean.destroy().

try (var context = new AnnotationConfigApplicationContext(ScopeConfig.class)) {
  ShoppingCart cart = context.getBean(ShoppingCart.class);   // ShoppingCart @PostConstruct
  context.getBeanFactory().destroyBean(cart);                 // ShoppingCart @PreDestroy
}

Without the destroyBean() call, the program prints only ShoppingCart @PostConstruct, even though the context closes.

10.3. Why Is @PreDestroy Not Called at All?

We check the common causes in this order.

  • The context is never closed. A plain main() method needs try-with-resources, close() or registerShutdownHook(), as we saw in section 8.
  • The bean has prototype scope, as section 10.2 shows.
  • The import is javax.annotation.PreDestroy, which Spring Framework 7 ignores.
  • The process is killed with kill -9, so the JVM runs no shutdown hooks.
  • A Spring application without Spring Boot has no jakarta.annotation-api on the classpath, or an XML configuration has no context:annotation-config element.

10.4. Is BeanPostProcessor Part of the Bean Life Cycle?

Yes. A BeanPostProcessor runs for every bean in steps 5 and 9 of the life cycle, once before and once after the init callbacks. We write one when the same logic must apply to many beans, for example to wrap them in a proxy, whereas a @PostConstruct method belongs to one bean only.

11. Conclusion

The Spring bean life cycle has a fixed order. Spring creates the bean, injects the dependencies and calls the Aware methods. After that, it runs the post processors and the init callbacks in the order @PostConstruct, afterPropertiesSet() and the custom init method.

The destroy callbacks follow the same pattern with @PreDestroy, destroy() and the custom destroy method. They run only for singleton beans, and only when the context closes, which Spring Boot does from its shutdown hook and a plain Spring application must do with close() or registerShutdownHook().

For our own classes, @PostConstruct and @PreDestroy are the recommended choice, and for third-party classes, @Bean(initMethod, destroyMethod) does the same job. The life cycle order is also a commonly asked Spring interview question.

12. References

Happy Learning !!

Source Code on Github

Leave a Comment

  1. Hi Lokesh, Please tell me which are the default bean life cycle methods called by the Spring container ?

  2. Hi Lokesh, I have one doubt. I have created a small project with 1 bean class, main class and context.xml file. What are the default interfaces implemented by bean behind the scenes if i wont implement any of them manually? Will it implements all the interfaces listed above or any particular mandatory interfaces it will implement ? Please help me in this, as i am stuck in this doubt without moving forward.

    • By default, a bean does not implement any of above interfaces. Above interfaces are used for executing code blocks on specific lifecycle event on a bean, and so these are used as and when needed only.

      • Thanks a lot Lokesh. I am clear now, as u said they are used when needed only. But,one doubt still persists. Spring container handles each and every beans life cycle defined in context.xml file. What are those mandatory life cycle methods( and these methods belongs to which interfaces ?) called by the Spring container. Example :- I have a single bean class, context file and Test class, and when i run Test class, which are the default methods called on the bean.
        Please bear my questions, which would help me lot :-).

        • By default, you can have two methods “init-method” and “destroy-method”. These methods then must be defined inside bean class. Spring framework internally uses reflection to invoke these methods.

  3. Nice Explanation. But could you Please discuss more about “Other Aware Interfaces…” and implementation of all these type.

    Thanks
    Tofek

  4. Hi,
    Thanks for the above information .It is really helpful.

    I had a requirement in my project, need to run the database scripts through liquibase. There is existing framework to check the change logs and run the change logs . So, just bean definition for this java class is enough to run the liquibase script changes for the entire project . This i have done as below
    <bean id = "lbase" class="com.*.*.**.<> datasource=”datasource” />

    Now, I had another webservice client configuration class which handles the code to read the webservice url and username from database.And the table will be created and loaded with data by the above defined liquibase bean. I have defined this webservice configuration bean as

    The order of defining in spring context file is firstly,liquibase related bean and then wsClientConfig bean is defined.
    now, the doubt is -among these two, which bean is initialized first and which is next?
    For me, error is coming as- no table or view exists while fetching the details of webservice fails.

    Please help in handling this scenario. Thank you

  5. I have a doubt.Spring works on the top of the underline java its means JVM .Why spring beans required one more life cycle it means that already jvm will have a life cycle

    • JVM does not manage it’s bean’s lifecyle. It’s container for all objects, and it checks which objects are live or dead. JVM never tries to modify the state or behavior of an object. objects are just created inside JVM and cleanup by it when they are no longer referred from other objects. That’s it !!

      Spring bean life cycle is different thing. Here you want to change the state/behavior of bean (or application) whenever an object get’s created or destroyed, or in some specific events. Please note that these events are not JVM triggered events. They are simple “callback methods” when spring’s IOC framework create those bean instances or destroy them.

  6. Hi, Lokesh Thanks a lot for this meaningful blog . i have one question which is related to beans life cycle i understood when public void afterPropertiesSet() has called but i have one confusion when public void destroy() will call and who call public void destroy() . and who is responsible to destroy spring bean?

  7. Hai am very new to spring .I am getting some problem in Spring bean lifecycle methods.Like
    the out put is
    constructor
    setId
    setName
    This is init-method
    Jul 10, 2014 9:58:35 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
    INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2a5330: defining beans [st]; root of factory hierarchy
    constructor
    setId
    setName
    before
    This is init-method
    after
    This is bussinessmethod
    means constructor and setters methods are called two times.what happen will anyone suggest me

    • The reason is – spring aop is proxy-based, i.e. the container creates “raw” bean instance and proxy for it (created at runtime via subclassing original bean class) if the bean is affected by AOP rules. So, when proxy object is created, it calls superclass constructor/setters and it looks as two instances are created.

      You notice that “before” and “after” methods are not called because they are run only when actual instance is created. It’s contract provided by Spring’s annotations @PostConstruct and @PreDestroy; OR “init-method” and “destroy-method” attributes of the bean element in configuration file.

    • Thanks for your reply.I understand well.Small thing is here am not using Aop concept.i just tries it by implenting BeanPostProcessor interface.And one more thing is if i add bean scope is “singleton” then BeforeInitialization and afterInitialization methods are not called.Plz explain me abt is there any internal relation between bean scopes and BeanPostProcessor interface methods. in BeanLife management.plz reply me.

  8. Hi, Thanks for your blog. I have one requirement in my current project like i need to start a new thread in my spring application. In that thread i need to call one of the beans methods. Would you please suggest.

    • If the object (thread instance) that needs access to the container is a bean in the container, just implement the BeanFactoryAware or ApplicationContextAware interfaces.

      If an object outside the container needs access to the container, you must use singleton pattern for the spring container. Create this singleton bean in application startup, and set the application context reference there in a variable. Now whenever you need a bean, get the context via singleton class, and lookup the bean from application context.

  9. Hi, Thanks a lot for this meaningful blog, I have in a problem please help me to solve it.
    Problem: How to prevent serialization in java if the class has implemented Serializable interface. Problem might be like this,
    Class A implements Seralizable{
    }
    class B extends A{
    }

    How to prevent class B to serialize if it have behavior of serialization if someone going to serialize. Please give me innovative solution.

    Hope i will hear you soon.

    Regard’s
    Santosh Srivastava

    • Not possible. Reason is that in java super class can not see the internals of child classes. Only child classes can access super class’s fields and methods. Anyway, what kind of design is this in which super class is serializable but child classes are not?? Please refer to “Liskov’s Substitution Principle” in https://howtodoinjava.com/best-practices/solid-principles/

      Anyways, you have following options:

      1) Make super class final so that no one can extend it? [I know it is not what you expect].
      2) Make super class’s field transient, so that if B is serialized then it will have only its state saved.

      Anybody came across this conversation, feel free to engage. :)

      • In Java, if the super class of a class is implementing Serializable interface, it means that it is already serializable. Since, an interface cannot be unimplemented, it is not possible to make a class non-serializable. However, the serialization of a new class can be avoided. For this, writeObject () and readObject() methods should be implemented in your class so that a Not Serializable Exception can be thrown by these methods. And, this can be done by customizing the Java Serialization process. Below the code that demonstrates it

        class MySubClass extends SomeSerializableSuperClass 
        {
        	private void writeObject(java.io.ObjectOutputStream out) throws IOException {
        	throw new NotSerializableException(“Can not serialize this class”);
        	}
        	private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
        		throw new NotSerializableException(“Can not serialize this class”);
        	}
        	private void readObjectNoData()	throws ObjectStreamException; {
        		throw new NotSerializableException(“Can not serialize this class”);
        	}
        }
        
  10. Hi
    thnx for the post
    can u tell me how bean factory will come to know (incase of global) .which class hold init and destroy method

Comments are closed.

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.