WitnessTruth
WitnessTruth

Reputation: 589

Execute a method after the application starts using Spring

I have this structure in my Service component in my Spring:

@Autowired
PointController controller;
@Autowired
ParametroService parametroService;

Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
    @Override
    public void run() {
        List<IntRaptMec> allPointments =  getNotValidated();

        for(IntRaptMec pointment : allPointments) {
           controller.validate(pointment.getIdTemp());
        }
    }
};        

public void doValidationsTask() {       

    Parametro parametroTempo = parametroService.getParametro("1", "ATRC_MEC", "TEMPO_VERIFICACAO");
    timer.scheduleAtFixedRate(
            timerTask,
            Integer.parseInt(parametroTempo.getValor()) * oneMinute,
            Integer.parseInt(parametroTempo.getValor()) * oneMinute
    );  

}

All that I want is that after the Spring Application fully initializes it will execute the method run() inside the TimerTask. Then, after a given time in minutes that will be get from the parametroService.getParametro(), execute this task again.

I tried to follow this link from the docs: https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#scheduling-annotation-support

But seems that I can't dinamically sets the Delay time that a specific task will be executed

Upvotes: 0

Views: 1088

Answers (5)

Rahul Vedpathak
Rahul Vedpathak

Reputation: 1436

You can implement a spring SmartLifecycle interface. This will get invoked when Spring context is loaded completely. And Then you can start the timertask.

public class TimerTaskInvoker implements SmartLifecycle{
@override
public void start(){
  timer.scheduleAtFixedRate(timerTask);
  }
}

You can check the reference - https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/SmartLifecycle.html

Upvotes: 1

Michael Gantman
Michael Gantman

Reputation: 7808

You are correct that annotation @Scheduled does not allow you to read delay parameter dynamically. For that reason and because this annotation takes delay parameter only in milliseconds or as crone expression which is not user friendly, I wrote my own utility that does it. The Utility is available as part of Open Source MgntUtils library. You will need to write your classes that will extend classes provided in the library and then you will get the desired functionality. But it does require a little bit of work. However the library comes with example package that has source code of working example with detailed explanation in javadoc. If you are interested library is available at Github and at Maven Central. In both places it is available with sources and javadoc. The desired feature is described in detail in javadoc. If you download and unzip javadoc into folder c:\tmp then look at URL file:///C:/tmp/javadoc/com/mgnt/lifecycle/management/backgroundrunner/package-summary.html for detailed description on how to use this feature. For working code example look in the sources at package com.mgnt.lifecycle.management.backgroundrunner.example
Also, there is an article that explains about the features of the library, except that this particular feature is not described in that article yet. Here is the link: Open Source Java library with stack trace filtering, Silent String parsing, Unicode converter and Version comparison

Upvotes: 2

Sahil Chhabra
Sahil Chhabra

Reputation: 11716

You can use spring scheduler and specify the initialDelay and fixedRate using the @Scheduled annotation.

@EnableScheduling
class CustomScheduler{

  @Scheduled(fixedRate = 1000, initialDelay = 1000)
  public void taskYouWantToPerform() {

      List<IntRaptMec> allPointments =  getNotValidated();
      for(IntRaptMec pointment : allPointments) {
          controller.validate(pointment.getIdTemp());
      }
  }
}

For more details refer this

Upvotes: 0

nirfrea
nirfrea

Reputation: 84

@PostConstruct may be the annotation you need.

https://www.baeldung.com/running-setup-logic-on-startup-in-spring

Upvotes: 1

diginoise
diginoise

Reputation: 7630

You can annotate your run() method with @EventListener or create a new such annotated method which will call run():

@EventListener
public void handleContextRefresh(ContextRefreshedEvent event) {
    run();
}

If you don't use context which supports refresh() operation, you should be fine. If you use such context (and you don't want run() to execute on context refresh) make sure you store this state within your bean.

More info on standard Spring events.

Upvotes: 2

Related Questions