Reputation: 4898
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
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