12/08/2018, 14:08

Tích hợp Quartz trong spring framework

Quartz là gì? Quartz là một thư viện mã nguồn mở lập lịch công việc(job),nó có thể được tích hợp bên trong bất kỳ ứng dụng java nào- từ ứng dụng nhỏ độc lập cho tới các ứng dụng thương mại điện tử lớn.Quartz thường được sử dụng để lập lịch cho các công việc đơn giản hoặc phức tạp như là ...

  1. Quartz là gì? Quartz là một thư viện mã nguồn mở lập lịch công việc(job),nó có thể được tích hợp bên trong bất kỳ ứng dụng java nào- từ ứng dụng nhỏ độc lập cho tới các ứng dụng thương mại điện tử lớn.Quartz thường được sử dụng để lập lịch cho các công việc đơn giản hoặc phức tạp như là 10,100 hoặc 1000 công việc,toàn bộ jobs được định nghĩa như là một thành phần chuẩn của java có thể được thi ở bất cứ đâu bạn muốn nó thực thi. Quartz Scheduler bao gồm nhiều đặc điểm của lớp hệ thống lớn như là hỗ trợ JTA transactions và clustering(là một công nghệ đảm bảo cho hệ thống vẫn hoạt động tốt ngay cả khi có sự cố xảy ra đối với máy chủ mạng)
  2. Tích hợp quartz với spring
  • Quartz sử dụng các đối tượng Trigger,Job và JobDetail để nhận thức việc lập lịch cho tất các các loại công việc.Để thuận tiện thì Spring đưa ra một vài class để đơn giản hóa việc sử dụng quartz bên trong ứng dụng dựa trên spring
  • Các bước tích hợp quartz trên project spring sử dụng maven
  1. Cập nhật file porm

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${springframework.version}</version>
    </dependency>
     
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${springframework.version}</version>
    </dependency>   
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>${quartz.version}</version>
    </dependency>
    
  2. Có hai cách để config một job trong spring sử dụng quartz 2.1) Sử dụng MethodInvokingJobDetailFactoryBean (cách 1)

    <bean id="simpleJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    
    <property name="targetObject" ref="myBean" /> <property name="targetMethod" value="printMessage" /></bean>

Đây cũng là cách đơn giản trong hai cách khi ban chỉ cần gọi môt phương thức trong một bean cụ thể Đoạn config trên đơn giản là gọi phương thức printMessage của myJobBean

2.2) Sử dụng JobDetailFactoryBean khi bạn cần thiết lập nâng cao,truyền dữ liệu tới job

     <bean name="complexJobDetail"    class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="study.spring.quartz.ScheduledJob" />
<property name="jobDataMap">
    <map>
        <entry key="anotherBean" value-ref="anotherBean" />
    </map>
</property>
<property name="durability" value="true" />
</bean>

jobClass tham chiếu tới một class đã extend QuartzJobBean.Khi job được gọi thực thi thì phương thức executeInternal sẽ được gọi 3) Cấu hình triggers để sử dụng trong quartz scheduler 3.1) trigger sẽ định nghĩa khi nào thì scheduler chạy job đã được lập lịch của bạn.Có hai loại trigger là simpler trigger và cron trigger 3.2) simple trigger,sử dụng SimpleTriggerFactoryBean:bạn có thể chỉ rõ thời gian bắt đầu,thời gian trễ giữa các triggers và số lần lặp khi chạy job

 <bean id="simpleTrigger"  class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="simpleJobDetail" />
<property name="startDelay" value="1000" />//khoảng thời gian delay từ khi ứng dụng start
<property name="repeatInterval" value="2000" />//khoảng thời gian giữa các lần gọi job
</bean>

3.2) Cron Trigger:sử dụng CronTriggerFactoryBean: nó động hơn so với simple trigger và nó cho phép bạn lựa chọn thực thi job vào một thời điểm cụ thể theo calendar trong tương lai

     <bean id="cronTrigger"  class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="complexJobDetail" />
<property name="cronExpression" value="0/5 * * ? * SAT-SUN" /></bean>

Biểu thức cron-expressions được ngăn cách bằng khoảng trắng và cấu trúc gồm có :

  1. Seconds
  2. Minutes
  3. Hours
  4. Day-of-Month
  5. Month
  6. Day-of-Week
  7. Year (optional field)

Trong ví dụ trên thì biểu thức sẽ có nghĩa là bắt đầu sau mỗi 5s chỉ vào các ngày cuối tuần. Các trường phải thiết lập các giá trị hợp lệ như là 0-59 cho giây và phút,0-23 cho giờ,day-of-month là từ 1-31,tháng là từ 0-11,hoặc sử dụng string như là JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC.Day-of-week là từ 1-7 hoặc SUN, MON, TUE, WED, THU, FRI and SAT.Ta có thể viết gọn từ thứ 2 tới thứ 6 bằng “MON-FRI” cho trường day-of-week hoặc kết hợp “MON,WED,FRI” cho thứ 2,3,4 hoặc “MON-WED,SAT” cho thứ 2,3,4,6 Một số dấu và ý nghĩa trong crossExpression: “*”:nghĩa là mỗi(every),trong ví dụ trên nghĩa là mỗi phút,mỗi giờ,mỗi tháng “?”:được dùng cho day-of-month hoặc day-of-week.Nó thường được sử dụng để chỉ ra là ko có giá trị cụ thể. “/”:ví dụ: ”0/15” trong trường phút thì nó có nghĩa là mỗi 15 phút của giờ đó,bắt đầu từ phút thứ 0, với “3/20” thì có nghĩa là mỗi 20 phút của giờ đó,bắt đầu từ phút thứ 3 tương đương với phút thứ 3,23,43 của giờ đó “L”:được dùng trong 2 trường là day-of-month và day-of-week,nó viết tắt cho “last” nhưng có nghĩa khác nhau trong mỗi trường.ví dụ L trong day-of-month nghĩa là ngày cuối cùng trong tháng,nếu sử dụng trong day-of-week có nghĩa là thứ 7 hay “SAT”.Nhưng nếu sử dụng trong trường day-of-week sau một giá trị khác thì nó có nghĩa là ngày xxx cuối cùng của tháng-ví dụ 6L thì là ngày thứ 6 cuối cùng của tháng đó.

  1. Cấu hình SchedulerFactoryBean để tạo và cấu hình Quartz Scheduler: SchedulerFactoryBean sẽ gắn jobDetails và triggers tới Quartz Scheduler

     <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="jobDetails"> <list> <ref bean="simpleJobDetail" /> <ref bean="complexJobDetail" /> </list> </property> <property name="triggers"> <list> <ref bean="simpleTrigger" /> <ref bean="cronTrigger" /> </list> </property>
</bean>

Dưới đây là toàn bộ file quartz-content.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

<context:component-scan base-package="study.spring" />

 
<bean id="simpleJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject" ref="myBean" />
    <property name="targetMethod" value="printMessage" />
</bean>

 
<bean name="complexJobDetail"    class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <property name="jobClass" value="study.spring.quartz.ScheduledJob" />
    <property name="jobDataMap">
        <map>
            <entry key="anotherBean" value-ref="anotherBean" />
        </map>
    </property>
    <property name="durability" value="true" />
</bean>

 
<bean id="simpleTrigger"  class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
    <property name="jobDetail" ref="simpleJobDetail" />
    <property name="startDelay" value="1000" />
    <property name="repeatInterval" value="2000" />
</bean>

 
<bean id="cronTrigger"  class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail" ref="complexJobDetail" />
    <property name="cronExpression" value="0/5 * * ? * SAT-SUN" />
</bean>

 
<bean  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="jobDetails">
        <list>
            <ref bean="simpleJobDetail" />
            <ref bean="complexJobDetail" />
        </list>
    </property>

    <property name="triggers">
        <list>
            <ref bean="simpleTrigger" />
            <ref bean="cronTrigger" />
        </list>
    </property>
</bean>
</beans> 5) Tạo các POJO’S Task Bean sử dụng trong ví dụ này
@Component("myBean") public class MyBean {

public void printMessage() {
    System.out.println("I am called by MethodInvokingJobDetailFactoryBean using SimpleTriggerFactoryBean");
}

}

@Component("anotherBean")
public class AnotherBean {
public void printAnotherMessage(){
    System.out.println("I am called by Quartz jobBean using CronTriggerFactoryBean");
}

} Bước 6:Tạo main và chạy ứng dụng

    public class AppMain {
public static void main(String args[]){
    AbstractApplicationContext context = new ClassPathXmlApplicationContext("quartz-context.xml");
}

} tài liệu tham khảo:

    http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-06.html
    http://websystique.com/spring/spring-4-quartz-scheduler-integration-example/
    http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html

Hi vọng những kiến thức tôi vừa chia sẻ sẽ hữu ích với bạn.

0