Best way to initialize beans in Spring context after application started?

We Are Going To Discuss About Best way to initialize beans in Spring context after application started?. So lets Start this Java Article.

Best way to initialize beans in Spring context after application started?

Advertisements
  1. Best way to initialize beans in Spring context after application started?

    I will enumerate other approaches in order to init beans, I grouped the approach in Standard Approach and Spring Boot Approach.

  2. Best way to initialize beans in Spring context after application started?

    I will enumerate other approaches in order to init beans, I grouped the approach in Standard Approach and Spring Boot Approach.

Solution 1

Advertisements

I will enumerate other approaches in order to init beans, I grouped the approach in Standard Approach and Spring Boot Approach.

Standard Approach

  1. @PostConstruct: it is just an annotation that triggers a method after bean is create, it doesn’t allow input parameters.
  2. @Bean(init-method="somInitMehotd"): this approach is totally related to Spring bean lifecycle and it is called after bean creation, if you are using another method with @PostConstruct annotation, then the @PostConstruct will be called first. This approach doesn’t allow input parameters.
  3. ApplicationListener: this interface allows to listen the standard events related to the Context Lifecycle, also it can listen customized events. For example: create a class MyAppListener and implements ApplicationListener<ContextRefreshedEvent> in this case the MyAppListener will implement an onApplicationEvent method that receives a ContextRefreshedEvent

Spring Boot Approach

  1. The runners: There are two very useful interfaces CommandLineRunner and ApplicationRunner both of them will run after ApplicationContext is created both of them allows to inject beans as input parameters.

  2. Spring boot listeners: Spring Application gives some additional events than the standards events that comes from the Application Context. One of the event is ApplicationReadyEvent and it is fire when the application is ready to receive request. In order to listen this events just implements the ApplicationListener using ApplicationReadyEvent as generic.

Here is the example:

MyBean class has different methods that will be called for each approach listed above, every method will call a print method and that method has a Thread.sleep in order to validate the order that every listener is called.

import javax.annotation.PostConstruct;
public class MyBean {

    private String myVar="";

    public MyBean(){

    }

    @PostConstruct
    public void postConstructInit(){

        this.myVar="Post init called";
        print();

    }

    public void beanInit(){

        this.myVar="Bean init called";
        print();
    }

    public void contextInit(){

        this.myVar="Context init called";
        print();
    }

    public void runnerInit(){

        this.myVar="Runner init called";
        print();
    }

    public void bootListenerInit(){

        this.myVar="Boot init called";
        print();
    }



    public void print(){
        System.out.println(this.myVar);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Here is the ContextRefreshListener class that will listen the ContextRefreshedEvent and handle it.

public class ContextRefreshListener implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        contextRefreshedEvent.getApplicationContext().getBean(MyBean.class).contextInit();

    }
}

And it is the BootListener that will receive the ApplicationReadyEvent that comes from Spring Application.

public class MyBootListener implements ApplicationListener<ApplicationReadyEvent> {
    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        applicationReadyEvent.getApplicationContext().getBean(MyBean.class).bootListenerInit();
    }
}

And finally the Spring Boot Application

@SpringBootApplication
public class StackoverflowBootApplication {


    public static void main(String[] args) {

        SpringApplication.run(StackoverflowBootApplication.class, args);

    }

    @Bean(name = "myBean", initMethod = "beanInit")
    public MyBean getMyBean(){
        return new MyBean();
    }


    @Bean
    public ContextRefreshListener getContextRefreshedListener(){return new ContextRefreshListener();}


    @Bean
    public MyBootListener getBootListener(){return new MyBootListener();}

    @Bean
    public CommandLineRunner getRunner(ApplicationContext ctx){
        return (args) -> {
            ctx.getBean(MyBean.class).runnerInit();
        };
    }

}

The output is:

Post init called
Bean init called
Context init called
Runner init called 
Boot init called

Post init called output comes from

@PostConstruct
public void init(){
    this.initByPostconstruct="Post init called";

Bean init called comes from the initMethod value

@Bean(name = "myBean", initMethod = "beanInit")
public MyBean getMyBean(){
    return new MyBean();
}
}

Context init called comes from ContextRefreshedEvent

public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
    contextRefreshedEvent.getApplicationContext().getBean(MyBean.class).contextInit();

}

Runner init called comes from CommandLineRunner

@Bean
public CommandLineRunner getRunner(ApplicationContext ctx){
    return (args) -> {
        ctx.getBean(MyBean.class).runnerInit();
    };
}

Boot init called comes from ApplicationReadyEvent

   public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        applicationReadyEvent.getApplicationContext().getBean(MyBean.class).bootListenerInit();
    }

All the listed scenarios were triggered by Spring, I didi’nt call any of the events directly, all of them were called by Spring Framework.

Original Author Daniel C. Of This Content

Conclusion

Advertisements

So This is all About This Tutorial. Hope This Tutorial Helped You. Thank You.

Also Read,

Advertisements
Siddharth

I am an Information Technology Engineer. I have Completed my MCA And I have 4 Year Plus Experience, I am a web developer with knowledge of multiple back-end platforms Like PHP, Node.js, Python and frontend JavaScript frameworks Like Angular, React, and Vue.

Leave a Comment