e11438
e11438

Reputation: 904

Scheduling a task with Spring

I'm using Java's Spring framework for my web application and I want to schedule a task to run in the server at particular time. The time is given by user of the application.

I looked into TaskScheduler and I found examples like,

@Configuration
@EnableAsync
@EnableScheduling
public class MyComponent {

    @Async
    @Scheduled(fixedDelay=5000)
    public void doSomething() {
       System.out.println("Scheduled Task");
    }
}

Same task happen over and over again in regular intervals. It prints "Scheduled task" in every 5 seconds, but I want to print that only one time (ex: at 11.35 am).

How can I print it only one time?

Upvotes: 2

Views: 230

Answers (2)

Matt C
Matt C

Reputation: 4555

Simplest fix, perhaps not best for practice

The easy fix is to add an if statement to your method and only print if the current time matches the time that you do want to print out.

Java has not always had the best time/date implementations, but as of Java 8, there is a new library called LocalDateTime and it works nicely. I think using it will be your best bet for this simple solution.

Here's an example of using LocalDateTime to get the current hour, minute, and second. There are similar methods for year, month, day, etc.

LocalDateTime now = LocalDateTime.now();
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();

We can combine this with your current code to only have the print statement executed at the time you desire:

@Configuration
@EnableAsync
@EnableScheduling
public class MyComponent {

    @Async
    @Scheduled(fixedDelay=5000)
    public void doSomething() {

        LocalDateTime now = LocalDateTime.now();
        int hour = now.getHour();
        int minute = now.getMinute();
        int second = now.getSecond();

        if(hour == 10 &&
           minute == 34 &&
           second < 6) {

            System.out.println("Scheduled Task");

        }
 
    }

}

You'll compare hour to 10 and minute to 34 because these functions return a number from 0 to n-1 where n is the number of hours in a day or minutes in an hour. You'll compare second to <6 so that no matter when this job starts (since it is executed once every 5 seconds) you'll always print at least once every day at 11:35am.


I'm definitely not trying to suggest that this is the best option, but it is definitely an option. Making a new instance of LocalDateTime every 5 seconds isn't ideal, but if resources aren't a problem then it's fine.

It's not the prettiest or best designed solution, but it works. This is an option if you just want a quick solution and you don't care about the correct "practice" for accomplishing this task.

Upvotes: 0

Vishal
Vishal

Reputation: 589

If you want to run the task only once, then you will have to give the cron expression such that it includes the entire date and time (including year) so it it gets matched only once.

Upvotes: 1

Related Questions