Sumit
Sumit

Reputation: 2426

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?

Upvotes: 9

Views: 25862

Answers (3)

Ananthapadmanabhan
Ananthapadmanabhan

Reputation: 6206

In your particular case , you need to reset the database after application deployment, so the best way for you to do that is to use the Spring CommandLineRunner .

Spring boot provides a CommanLineRunner interface with a callback run() method which can be invoked at application startup after the Spring application context is instantiated.

CommandLineRunner beans can be defined within the same application context and can be ordered using the @Ordered interface or @Order annotation.

@Component
public class CommandLineAppStartupRunnerSample implements CommandLineRunner {
    private static final Logger LOG =
      LoggerFactory.getLogger(CommandLineAppStartupRunnerSample .class);

    @Override
    public void run(String...args) throws Exception {
        LOG.info("Run method is executed");
        //Do something here
    }
}

Answer referred from site : https://www.baeldung.com/running-setup-logic-on-startup-in-spring

Upvotes: 0

madz
madz

Reputation: 1863

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

Upvotes: 2

Ioan M
Ioan M

Reputation: 1207

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

Upvotes: 12

Related Questions