web123456

How to use Spring ApplicationListener and problems

Use scenarios

In some business scenarios, after the container initialization is completed, some operations need to be processed, such as loading some data, initialization cache, registration of specific tasks, etc. At this time, we can use the ApplicationListener provided by Spring to perform operations.

usage

This article uses the use under Spring boot as an example to illustrate. First, it is necessary to implement the ApplicationListener interface and implement the onApplicationEvent method. Put the operations that need to be processed in the onApplicationEvent for processing:

package com.secbro.learn.context;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

/**
 * Created by zhuzs on 2017/5/12.
 */
public class ApplicationStartListener implements ApplicationListener<ContextRefreshedEvent>{
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        System.out.println("My parent container is:" + contextRefreshedEvent.getApplicationContext().getParent());
        System.out.println("I was called when initialized.");
    }
}

Then, instantiate the ApplicationStartListener class and instantiate it in Spring boot through a configuration class:

package ;

import ;
import ;
import ;

/**
 * Created by zhuzs on 2017/5/12.
 */
@Configuration
public class ListenerConfig {

    @Bean
    public ApplicationStartListener applicationStartListener(){
        return new ApplicationStartListener();
    }
}

Then, start the Spring boot service and print out the content:

My parent container is:nullI was called when initialized.

From the printed result, we can see that the onApplicationEvent method of ApplicationStartListener has been successfully called when the container is started. The initialized container at this time is the root container.

Secondary call problem

Here, Spring boot is used to operate, and there is no problem with secondary calls. The problem of secondary calls occurs when using traditional and configurations. The main reason is that after initializing the root container, the corresponding subcontainer will be initialized. What we need is to execute it only once. Then the code that prints the parent container above is used to determine and exclude the child container. Add the following judgment before business processing:

if(().getParent() != null){
            return;
}

In this way, the initialization of other containers will be returned directly, and the corresponding business operations will be performed when the parent container (the container with Parent is null) is started.

Related knowledge

In spring, the InitializingBean interface also provides similar functions, except that it operates when it is called after all beans are instantiated. Depending on different business scenarios and needs, different solutions can be selected to implement them.