Skip to content

Lab M06P01

  1. Enable scheduling with the @EnableScheduling annotation on Application class

  2. Implement a library checker component, which periodically checks number of books in library every 3 seconds. Use the @Scheduled annotation on handler method. This method will be scheduler by Spring task scheduler for execution.

      @Component
      public class LibraryChecker {
        private static final Logger LOG = LoggerFactory.getLogger(LibraryChecker.class);
        private LibraryService libraryService;
    
        public LibraryChecker(LibraryService libraryService) {
          this.libraryService = libraryService;
        }
    
        @Scheduled(initialDelay = 2000, fixedRate = 3000)
        public void check(){
          LOG.info("--- [check] Library contains {} books ---", libraryService.getAllBooks().size());
        }
      } 
    
  3. Add test to verify, if scheduler works correctly.

      import org.awaitility.Duration;
      import static org.awaitility.Awaitility.await;
      import static org.mockito.Mockito.atLeast;
      import static org.mockito.Mockito.verify;
    
      @SpringBootTest
      public class LibraryCheckerTest {
    
        @SpyBean
        LibraryChecker libraryChecker;
    
        @Test
        public void checkTest(){
          await().atMost(Duration.TEN_SECONDS).untilAsserted(() -> {
              verify(libraryChecker, atLeast(2)).check();
          });
        }
      }
    
  4. You can, configure custom task scheduler bean and use its API for programmatic scheduling.

      @Bean
      public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
          ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
          threadPoolTaskScheduler.setPoolSize(10);
          threadPoolTaskScheduler.setThreadNamePrefix("my-scheduler");
          return threadPoolTaskScheduler;
      }  
    
  5. Extends the LibraryChecker with method for initialization of a programmatic scheduler. You need to implement Runnable Task.

      @Component
      public class LibraryChecker {
        private static final Logger LOG = LoggerFactory.getLogger(LibraryChecker.class);
    
        private LibraryService libraryService;
        private TaskScheduler threadPoolTaskScheduler;
    
        public LibraryChecker(LibraryService libraryService, TaskScheduler threadPoolTaskScheduler) {
          this.libraryService = libraryService;
          this.threadPoolTaskScheduler = threadPoolTaskScheduler;
        }
    
        public void checkWithScheduler(long rate){
            LOG.info("Scheduling task using task scheduler...");
            threadPoolTaskScheduler.scheduleAtFixedRate(new LibraryTask("checkWithScheduler"), rate);
        }
    
        class LibraryTask implements Runnable{
          private String name;
    
          public LibraryTask(String name){
            this.name = name;
          }
    
          @Override
          public void run() {
            LOG.info("---[{}}] Library contains {} books ---", name, libraryService.getAllBooks().size());
          }
        }
      }
    
  6. You can also use Trigger to schedule task.

       public void checkWithSchedulerTrigger(Trigger trigger){
         LOG.info("Scheduling task using triggered task scheduler...");
         threadPoolTaskScheduler.schedule(new LibraryTask("checkWithSchedulerTrigger"), trigger);
       }
    
      // Every 5 seconds
      CronTrigger cronTrigger = new CronTrigger("0/5 * * * * ?");
      libraryChecker.checkWithSchedulerTrigger(cronTrigger);