Saturday, November 5, 2022

 

Quartz Scheduler with SpringBoot (Phần 1)


  • An endpoint, to show current items in the system.
  • A quartz job, to keep adding a new item at a regular interval.

1. Maven Project:

<dependency>    
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

2. Main class:

@SpringBootApplication 
public class QuartzSpringApplication {
public static void main(String[] args {
SpringApplication.run(QuartzSpringApplication.class, args);
}
}
  • Added @SpringBootApplication annotation on the main class.
  • Called the static SpringApplicatio.run function from the main method.
  • Added webFlux dependency in pom.xml in the previous step,

3. Model class:

@Getter
@Setter
@AllArgsConstructorpublic
class Book {
private UUID id;
private String name;
private String description;
private String authorName;
private BigDecimal cost;
}

4. Repository class:

  • A property List<Book>, that will be used as a Database.
  • A method getAllBooks, will be used by the Controller to read data
  • A method addBook, will be used by Quartz job to save a new book at regular intervals.
@Component
public class BookRepository { private final List<Book> books = new ArrayList<>(); public List<Book> getAllBooks(){
return books;
}
public void addBook(Book book){
books.add(book);
}
public int getBooksCount(){
return books.size();
}
}

5. Controller class:

@RestController
@RequestMapping("/books")
public class BooksController { private final BookRepository bookRepository; public BooksController(BookRepository bookRepository) {
this.bookRepository = bookRepository;
} @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE)
List<Book> getBooks() {
return bookRepository.getAllBooks();
}
}

6. Job class:

@Slf4j
@Component
public class LoadBookJob implements Job { final BookRepository bookRepository; public LoadBookJob(BookRepository bookRepository) {
this.bookRepository = bookRepository;
} @Override
public void execute(JobExecutionContext context)
throws JobExecutionException
{ int booksCounter = bookRepository.getBooksCount() + 1; log.info("Adding book number {} ", booksCounter); bookRepository
.addBook(new Book(UUID.randomUUID(),
"name" + booksCounter,
"description" + booksCounter,
"author" + booksCounter,
BigDecimal.valueOf(booksCounter + 100)));
}
}

7. QuartzConfiguration class:

  1. JobDetailFactoryBean
    At startup, spring will use this to create JobDetail beans, to pass to trigger the creation
  2. SimpleTriggerFactoryBean At startup spring will use this to create Triggers to pass to SchedulerFactoryBean creation
@Slf4j
@Configuration
public class QuartzConfig { /**
----------------------------
To complete this config class
we will add some more code at this location.
First look at the below lines and understand
----------------------------
**/
@Bean
public SimpleTriggerFactoryBean
createSimpleTriggerFactoryBean(JobDetail jobDetail)
{
SimpleTriggerFactoryBean simpleTriggerFactory
= new SimpleTriggerFactoryBean();

simpleTriggerFactory.setJobDetail(jobDetail);
simpleTriggerFactory.setStartDelay(0);
simpleTriggerFactory.setRepeatInterval(5000);
simpleTriggerFactory.setRepeatCount(10);
return simpleTriggerFactory;
} @Bean
public JobDetailFactoryBean createJobDetailFactoryBean(){

JobDetailFactoryBean jobDetailFactory
= new JobDetailFactoryBean();
jobDetailFactory.setJobClass(LoadBookJob.class);
return jobDetailFactory;
}
}
final ApplicationContext applicationContext;

public QuartzConfig(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}

@Bean
SpringBeanJobFactory createSpringBeanJobFactory (){

return new SpringBeanJobFactory() {

@Override
protected Object createJobInstance
(final TriggerFiredBundle bundle) throws Exception {

final Object job = super.createJobInstance(bundle);

applicationContext
.getAutowireCapableBeanFactory()
.autowireBean(job);

return job;
}
};
}@Bean
public SchedulerFactoryBean createSchedulerFactory
(SpringBeanJobFactory springBeanJobFactory,Trigger trigger) {

SchedulerFactoryBean schedulerFactory
= new SchedulerFactoryBean(); schedulerFactory.setAutoStartup(true);
schedulerFactory.setWaitForJobsToCompleteOnShutdown(true);
schedulerFactory.setTriggers(trigger);

springBeanJobFactory.setApplicationContext(applicationContext);
schedulerFactory.setJobFactory(springBeanJobFactory);

return schedulerFactory;
}

Explanation of the above code snippet:

Moment of Truth:

No comments:

Post a Comment

So sánh các GitFlow model và áp dụng với CICD

https://medium.com/oho-software/so-s%C3%A1nh-c%C3%A1c-gitflow-model-v%C3%A0-%C3%A1p-d%E1%BB%A5ng-v%E1%BB%9Bi-cicd-b6581cfc893a