Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call a method after Spring Boot app starts

I have a Java Spring Boot application which has a Scheduler which calls a async task from a Service The task takes a few minutes (usually 3-5mins) to complete.

The same async method from the Service can also be called trough a UI Application, by calling the API from the Spring Boot Controller.

Code:

Scheduler

@Component
public class ScheduledTasks {
  @Autowired
  private MyService myService;

  @Scheduled(cron = "0 0 */1 * * ?")
  public void scheduleAsyncTask() {
    myService.doAsync();
  }
}

Service

@Service
public class MyService {
  @Async("threadTaskExecutor")
  public void doAsync() {
    //Do Stuff
  }
}

Controller

@CrossOrigin
@RestController
@RequestMapping("/mysrv")
public class MyController {
  @Autowired
  private MyService myService;

  @CrossOrigin
  @RequestMapping(value = "/", method = RequestMethod.POST)
  public void postAsyncUpdate() {
    myService.doAsync();
  }
}

The scheduler runs the async task every hour, but a user can also run it manually from the UI.

But, I do not want the async method to run again if it is already in the middle of execution.

In order to do that, I have created a table in DB which contains a flag which goes on when the method is running and then it is turned off after the method completes.

Something like this in my service class:

@Autowired
private MyDbRepo myDbRepo;

@Async("threadTaskExecutor")
public void doAsync() {
  if (!myDbRepo.isRunning()) {
    myDbRepo.setIsRunning(true);
    //Do Stuff
    myDbRepo.setIsRunning(false);
  } else {
    LOG.info("The Async task is already running");
  }
}

Now, the problem is that the flag sometimes gets stuck due to various reasons (app restarting, some other application error etc.)

So, I want to reset the flag in DB each time the spring boot application is deployed and whenever is restarts.

How can I do that? Is there some way to run a method just after the Spring Boot Application starts, from where I can call a method from my Repo to un set the flags in the database?

like image 837
Sumit Avatar asked Apr 26 '19 20:04

Sumit


People also ask

How do you call a method on startup in spring boot?

Spring boot provides an ApplicationRunner interface with a run() method to be invoked at application startup. However, instead of raw String arguments passed to the callback method, we have an instance of the ApplicationArguments class.

How would you call a method before starting loading in spring boot application?

2.6. Spring Boot provides a CommandLineRunner interface with a callback run() method. This can be invoked at application startup after the Spring application context is instantiated.

What happens when a spring boot application starts?

Spring Boot automatically configures your application based on the dependencies you have added to the project by using @EnableAutoConfiguration annotation. For example, if MySQL database is on your classpath, but you have not configured any database connection, then Spring Boot auto-configures an in-memory database.

How can we call a method after bean initialization in spring boot?

Hello Friends, If you Want to call the method after your bean is initialize in spring you can use the following options. Use the afterProprtiesSet method. 2:- You can use the annotation @PostConstruct in your class. to enable this you need to define in your application context xml file.


2 Answers

Check for the @PostConstruct for e.g here https://www.baeldung.com/running-setup-logic-on-startup-in-spring

like image 134
Ioan M Avatar answered Nov 15 '22 19:11

Ioan M


If you want to do some stuff after whole application booted and ready use below sample from

import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class ApplicationStartup 
implements ApplicationListener<ApplicationReadyEvent> {

  /**
   * This event is executed as late as conceivably possible to indicate that 
   * the application is ready to service requests.
   */
  @Override
  public void onApplicationEvent(final ApplicationReadyEvent event) {

    // here your code ...

    return;
  }

} // class

If it is enough to hook after a single bean creating use @PostConstruct as suggested by @loan M

like image 39
madz Avatar answered Nov 15 '22 17:11

madz