Spring scheduling task - run only once
You can use one of Spring's TaskScheduler's implementations. I provided an example below with one which does not require too much configuration (ConcurrentTaskScheduler that wraps a single-threaded scheduled executor).
The simplest method is the one named schedule that takes a Runnable
and Date only. That will cause the task to run once after the
specified time. All of the other methods are capable of scheduling
tasks to run repeatedly.
Read more on task execution & scheduling
Simple working example:
private TaskScheduler scheduler;
Runnable exampleRunnable = new Runnable(){
@Override
public void run() {
System.out.println("Works");
}
};
@Async
public void executeTaskT() {
ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor();
scheduler = new ConcurrentTaskScheduler(localExecutor);
scheduler.schedule(exampleRunnable,
new Date(1432152000000L));//today at 8 pm UTC - replace it with any timestamp in miliseconds to text
}
...
executeTaskT() //call it somewhere after the spring application has been configured
Note:
To enable support for @Scheduled and @Async annotations add
@EnableScheduling and @EnableAsync to one of your @Configuration
classes
Update - cancelling the scheduled task
TaskScheduler's schedule method returns a ScheduledFuture which is a delayed result-bearing action that can be cancelled.
So in order to cancel it, you need to keep a handle to the scheduled task (i.e. keep the ScheduledFuture return object).
Changes to the code above for cancelling the task :
- Declare the ScheduledFuture outside your executeTaskT method.
private ScheduledFuture scheduledFuture;
- Modify your call to schedule to keep the return object as such:
scheduledFuture = scheduler.schedule(exampleRunnable,
new Date(1432152000000L));
- Call cancel on the scheduledFuture object somewhere in your code
boolean mayInterruptIfRunning = true;
scheduledFuture.cancel(mayInterruptIfRunning);
How to run @Scheduled job at exact time for once in Spring?
This is a workaround to your solution. Just use the scheduled annotation as it is but Use Date with it. That is
String targetDate="2020-02-06 13:50:00";
Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(targetDate);
if(new Date().getTime()==date.getTime())
{
then put your logic here.
}
edit -> Just checking the year would be enough right. So you can do this.
@Scheduled(cron = "0 50 13 6 2 ?")
public void doTheJobForOnceInSpecificTime() {
if (Year.now().getValue() == 2020) {
//your logic
}
}
Spring, Run task once when application started
If it has to be run once immediately after application is initialized, I would simply start it from the init method of a singleton bean. Spring ensures that at be time it will be run all dependant beans will have been initialized.
For example, assuming a Java annotation Spring configuration you could use something like:
@Bean(init_method="init")
class TaskLauncher {
@Autowired DependantBeanClass dependant Bean;
...
public void init() {
// execute or start the task, eventually using the autowired dependant beans
...
}
}
When the context is refreshed, Spring autowire everything, initializes the dependant beans and then will call once the init
method of the TaskLauncher
bean.
No need for @Scheduler nor Quartz if you only need to start something at Spring initialization time
Related Topics
Java 8: How to Work with Exception Throwing Methods in Streams
Using Javafx.Beans Properties in Model Classes
Apache Spark - Foreach VS Foreachpartition When to Use What
Is Executorservice (Specifically Threadpoolexecutor) Thread Safe
Sum All the Elements Java Arraylist
Process Thymeleaf Variable as HTML Code and Not Text
Extract Integer Part in String
Using Ntlm Authentication in Java Applications
Accessing Kotlin Extension Functions from Java
How to Use Regular Expressions in Web.Xml Url Patterns
Java Lambda Returning a Lambda
Hibernate Bidirectional @Manytoone, Updating the Not Owning Side Not Working
How to Determine If a String Has Non-Alphanumeric Characters
Determining Current Call Stack (For Diagnostic Purposes)
How to Find a Definitive Selenium Webdriver to Firefox Compatibility Matrix