Tuesday, 18 December 2018

Spring+Quartz Scheduler Integration Example (JobDetailFactoryBean) | Spring Tutorial

Enjoying the Spring Tutorial?

Subscribe to Ram N Java for clean, hands-on Java & Spring guides!

SUBSCRIBE NOW

1. Introduction to Spring & Quartz Integration

Scheduling background jobs is an essential part of enterprise Java development. Quartz is a powerful, open-source job scheduling library, and Spring provides convenient factory beans to wire up Quartz components effortlessly.

In this guide, you will learn how to configure a scheduled job using JobDetailFactoryBean, pass custom objects using jobDataAsMap, and execute tasks on an interval using CronTriggerFactoryBean.

2. Required Maven Dependencies

To integrate Quartz with Spring Framework, include the Spring Context Support and Quartz dependencies in your pom.xml:

<!-- Spring Context Support -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>5.x.x.RELEASE</version>
</dependency>

<!-- Quartz Scheduler -->
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.x</version>
</dependency>

3. Creating the Service and Job Classes

First, create a simple service component that performs our target work—in this case, printing the current timestamp:

@Component("reportCurrentTime")
public class ReportCurrentTime {
    public void printCurrentTime() {
        System.out.println("Current Time: " + new Date());
    }
}

Next, extend Spring's QuartzJobBean and override the executeInternal method to perform the work when triggered:

public class ScheduledJob extends QuartzJobBean {
    private ReportCurrentTime reportCurrentTime;

    public void setReportCurrentTime(ReportCurrentTime reportCurrentTime) {
        this.reportCurrentTime = reportCurrentTime;
    }

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        reportCurrentTime.printCurrentTime();
    }
}

4. Spring XML Configuration

Configure the beans in your Spring configuration file:

  • JobDetailFactoryBean: Defines the job class and injects application beans via jobDataAsMap.
  • CronTriggerFactoryBean: Defines the schedule (e.g., cron expression 0/5 * * * * ? to execute every 5 seconds).
  • SchedulerFactoryBean: Ties together the triggers and manages scheduler execution.

5. Execution and Output

When running the application with ClassPathXmlApplicationContext, the Quartz scheduler automatically initializes, executing your job method every 5 seconds and logging the active timestamp directly to the console.


Related Video Tutorials


Click here to watch on Youtube:
https://www.youtube.com/watch?v=G22H6Y5Ig3U&list=UUhwKlOVR041tngjerWxVccw

Click the below Image to Enlarge:
Spring+Quartz Scheduler Integration Example (JobDetailFactoryBean) | Spring Tutorial

Spring+Quartz Scheduler Integration Example (JobDetailFactoryBean) | Spring Tutorial

Spring+Quartz Scheduler Integration Example (JobDetailFactoryBean) | Spring Tutorial
pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ram.core</groupId>
    <artifactId>SpringDemo</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>SpringDemo</name>
    <url>http://maven.apache.org</url>

    <properties>
        <springframework.version>5.1.2.RELEASE</springframework.version>
        <quartz.version>2.3.0</quartz.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <!-- Transaction dependency is required with Quartz integration -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${springframework.version}</version>
        </dependency>
     
        <!-- Quartz framework -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>${quartz.version}</version>
        </dependency>

    </dependencies>
</project>

ReportCurrentTime.java

package com.ram.scheduling;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.stereotype.Component;

@Component("reportCurrentTime")
public class ReportCurrentTime
{

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat(
            "HH:mm:ss");

    public void printCurrentTime()
    {
        System.out.println(
                "Current time = " + dateFormat.format(new Date()));
    }

}

ScheduledJob.java

package com.ram.quartz;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

import com.ram.scheduling.ReportCurrentTime;

public class ScheduledJob extends QuartzJobBean
{
    private ReportCurrentTime reportCurrentTime;

    @Override
    protected void executeInternal(JobExecutionContext arg0)
            throws JobExecutionException
    {
        reportCurrentTime.printCurrentTime();
    }

    public ReportCurrentTime getReportCurrentTime()
    {
        return reportCurrentTime;
    }

    public void setReportCurrentTime(
            ReportCurrentTime reportCurrentTime)
    {
        this.reportCurrentTime = reportCurrentTime;
    }

}

quartz-context.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="com.ram" />

    <!-- For times when you need more complex processing, passing data to the
        scheduled job -->
    <bean name="complexJobDetail"
        class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.ram.quartz.ScheduledJob" />
        <property name="jobDataMap">
            <map>
                <entry key="reportCurrentTime" value-ref="reportCurrentTime" />
            </map>
        </property>
        <property name="durability" value="true" />
    </bean>

    <!-- Daily run the job every 5 seconds -->
    <bean id="cronTrigger"
        class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="complexJobDetail" />
        <property name="cronExpression" value="0/5 * * ? * MON-SUN" />
    </bean>

    <!-- Scheduler factory bean to glue together jobDetails and triggers to
        Configure Quartz Scheduler -->
    <bean
        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="jobDetails">
            <list>
                <ref bean="complexJobDetail" />
            </list>
        </property>

        <property name="triggers">
            <list>
                <ref bean="cronTrigger" />
            </list>
        </property>
    </bean>

</beans>

App.java

package com.ram;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

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

}

Output

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Current time = 10:44:05
Current time = 10:44:10
Current time = 10:44:15
Current time = 10:44:20

Click the below link to download the code:
https://sites.google.com/site/ramj2eev2/java_basics/SpringDemo_Quartz_CronTriggerFactoryBean.zip?attredirects=0&d=1

Github Link:
https://github.com/ramram43210/javaee/tree/master/Spring_2018/SpringDemo_Quartz_CronTriggerFactoryBean

Bitbucket Link:
https://bitbucket.org/ramram43210/spring/src/0989e369f77ed192b0b224588ebfcdeb2019a6a2/Spring_2018/SpringDemo_Quartz_CronTriggerFactoryBean/?at=master

See also:

  • All JavaEE Videos Playlist
  • All JavaEE Videos
  • All JAVA EE Links
  • Spring Tutorial
  • Servlets Tutorial
  • All Design Patterns Links
  • JDBC Tutorial
  • Java Collection Framework Tutorial
  • JAVA Tutorial
  • Kids Tutorial
  • Cooking Tutorial
  • No comments:

    Post a Comment

    Tutorials