Enable Scheduling

Initialize a spring new project and add awaitility library.
 
<!-- Spring Boot Core -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- Awaitility for async tests -->
<dependency>
    <groupId>org.awaitility</groupId>
    <artifactId>awaitility</artifactId>
    <version>4.2.0</version>
    <scope>test</scope>
</dependency>

Example 1

Enable scheduling in you App with @EnableScheduling annotation.
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling  // Look Here
public class TimeApp {
    public static void main(String[] args) {
        SpringApplication.run(TimeApp.class, args);
    }
}
 
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;

@Component
public class TimeComponent {
    
    private static final SimpleDateFormat dateFormat = 
        new SimpleDateFormat("HH:mm:ss");

    @Scheduled(fixedRate = 1000)  // 1 sec
    public void runningTime() {
        System.out.println(
            "Time is: " + dateFormat.format(new Date())
        );
    }
}
 
mvn spring-boot:run

# Time is: 17:36:24
# Time is: 17:36:25
# Time is: 17:36:26

Example 2

Schedule a task with Spring Boot and test it using Awaitility.
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class CounterApp {
    public static void main(String[] args) {
        SpringApplication.run(CounterApp.class, args);
    }
}
 
import java.util.concurrent.atomic.AtomicInteger;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Service
public class CounterService {
    
    private final AtomicInteger counter = new AtomicInteger(0);

    @Scheduled(fixedRate = 1000)  // runs every 1 second
    public void increaseCounter() {
        counter.incrementAndGet();
        System.out.println("Counter increment: " + getCounter());
    }

    public int getCounter() {
        return counter.get();
    }
}
 
mvn spring-boot:run

# Counter incremented: 1
# Counter incremented: 2
# Counter incremented: 3

 
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.awaitility.Awaitility.await;
import java.time.Duration;

@SpringBootTest
public class CounterServiceTest {
    
    @Autowired
    private CounterService service;

    @Test
    void counterShouldIncreaseAutomatically() {
        
        // Wait up to 5 seconds until counter >= 2
        await()
            .atMost(Duration.ofSeconds(5))
            .until(() -> service.getCounter() >= 2);
    }
}
 
mvn test

[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

Example 3

This simulates calling an external market-data API, a random price is used instead of real HTTP calls.
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class FxApp {
    public static void main(String[] args) {
        SpringApplication.run(FxApp.class, args);
    }
}
 
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.concurrent.atomic.AtomicReference;

@Service
public class FxRateService {

    private final AtomicReference<Double> latestRate = new AtomicReference<>();

    // Simulate external API call
    private double fetchFxRateFromProvider() {
        return 4.5 + Math.random();  // pretend EUR/RON fluctuates
    }

    @Scheduled(fixedRate = 5000)  // every 5 seconds
    public void updateRate() {
        double newRate = fetchFxRateFromProvider();
        latestRate.set(newRate);
        System.out.println("FX updated: " + newRate);
    }

    public Double getLatestRate() {
        return latestRate.get();
    }
}
 
mvn spring-boot:run

FX updated: 5.216310420189029
FX updated: 5.298944643788635
FX updated: 5.039270121742039
 
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.awaitility.Awaitility.await;
import java.time.Duration;

@SpringBootTest
public class FxRateServiceTest {
    
    @Autowired 
    FxRateService fxRateService;

    @Test
    void fxRateShouldBeUpdatedByScheduler() {
        await()
            .atMost(Duration.ofSeconds(10))
            .until(() -> fxRateService.getLatestRate() != null);
    }
}
 
mvn test -Dtest=FxRateServiceTest

[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

Autowired (Note)

@Autowired is a Spring Framework annotations used for dependency injection. @Autowired tells Spring: "Find a suitable object (bean) and inject it here. Service depending on a repository.
 
@Repository
public class FxRateRepository {
    public double findRate() {
        return 4.75;
    }
}
 
@Service
public class FxRateService {

    @Autowired
    private FxRateRepository repository;

    // Equivalent to:
    // private FxRateRepository repository = new FxRateRepository();

    public double getRate() {
        return repository.findRate();
    }
}
Constructor injection (BEST PRACTICE). In modern Spring (Boot 2+), @Autowired is optional if there’s only one constructor.
 
@Service
public class FxRateService {

    private final FxRateRepository repository;

    @Autowired
    public FxRateService(FxRateRepository repository) {
        this.repository = repository;
    }
}
Field injection (NOT recommended). Hard to test, hides dependencies, cannot create object without Spring.
 
    @Autowired
    private FxRateRepository repository;




References: