Ealon
Ealon

Reputation: 4898

How to call functions in SpringApplicationRunListener

I have a SpringApplicationRunListener implementation like this.

public class AppListener implements SpringApplicationRunListener {
    private long appStartTimestamp;
    private long appFinishTimestamp;

    public AppListener(SpringApplication application, String[] args) {
    }

    @Override
    public void started() {
        appStartTimestamp = System.currentTimeMillis();
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        //Not used.
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        //Not used.
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        //Not used.
    }

    @Override
    public void finished(ConfigurableApplicationContext context, Throwable exception) {
        appFinishTimestamp = System.currentTimeMillis();
    }

    public long getAppStartTimestamp() {
        return appStartTimestamp;
    }

    public long getAppFinishTimestamp() {
        return appFinishTimestamp;
    }
}

Without using any static methods or variables, how can I call getAppStartTimestamp() and getAppFinishTimestamp() functions to get the two variables? Below code does not work because I initialize a new instance of AppListener.

AppListener appListener = new AppListener(new SpringApplicationBuilder(Application.class).build(), null);
appStartTimestamp = appListener.getAppStartTimestamp(); // 0
appFinishTimestamp = appListener.getAppFinishTimestamp(); // 0

I find that AppListener cannot be made as a bean because it is invoked before Spring starts bean management. Is there a way to get the running AppListener instance to call the two get functions? Thanks.

Upvotes: 1

Views: 3772

Answers (1)

Avinash
Avinash

Reputation: 4279

Create a POJO to hold the application event data

@Component
public class AppEventData {

    private long appStartTimestamp;
    private long appFinishTimestamp;

    public long getAppStartTimestamp() {
        return appStartTimestamp;
    }

    public void setAppStartTimestamp(long appStartTimestamp) {
        this.appStartTimestamp = appStartTimestamp;
    }

    public long getAppFinishTimestamp() {
        return appFinishTimestamp;
    }

    public void setAppFinishTimestamp(long appFinishTimestamp) {
        this.appFinishTimestamp = appFinishTimestamp;
    }
}

Now update your finish method of listener class to put the value of start and finish time in the POJO

public class AppListener implements SpringApplicationRunListener {
    private long appStartTimestamp;
    private long appFinishTimestamp;

    public AppListener(SpringApplication application, String[] args) {
        super();
    }

    @Override
    public void started() {
        appStartTimestamp = System.currentTimeMillis();
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        //Not used.
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        //Not used.
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        //Not used.
    }

    @Override
    public void finished(ConfigurableApplicationContext context, Throwable exception) {
        appFinishTimestamp = System.currentTimeMillis();
        AppEventData data = context.getBean(AppEventData.class);
        data.setAppStartTimestamp(appStartTimestamp);
        data.setAppFinishTimestamp(appFinishTimestamp);
    }

    public long getAppStartTimestamp() {
        return appStartTimestamp;
    }

    public long getAppFinishTimestamp() {
        return appFinishTimestamp;
    }
}

Now you can fetch the data from POJO from anywhere, for example I am showing you the main method.

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class, args);

        AppEventData data = ctx.getBean(AppEventData.class);
        System.out.println(data.getAppStartTimestamp());
        System.out.println(data.getAppFinishTimestamp());
    }
}

It's done....

Don't forget to put the listener in src/main/resources/META-INF/spring.factories like below otherwise the listener will not run.

org.springframework.boot.SpringApplicationRunListener=com.app.AppListener

Upvotes: 8

Related Questions