Showing posts with label Quartz Scheduler. Show all posts
Showing posts with label Quartz Scheduler. Show all posts

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
  • Monday, 17 December 2018

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

    Enjoying the Spring Tutorial?

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

    SUBSCRIBE NOW

    1. Understanding SimpleTriggerFactoryBean in Spring

    In enterprise applications, executing tasks at fixed intervals with an initial start delay is a standard requirement. While Quartz provides powerful cron triggers for complex schedules, SimpleTriggerFactoryBean is ideal for simple recurring jobs that need fixed repeat intervals.

    Spring encapsulates Quartz triggers into convenient factory beans, enabling easy dependency injection and clean lifecycle management directly within your Spring application context.

    2. Defining the Task and Service

    First, create the service component that encapsulates your business logic:

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

    Next, define your scheduled job class extending QuartzJobBean:

    public class SimpleScheduledJob extends QuartzJobBean {
        private ReportCurrentTime reportCurrentTime;
    
        public void setReportCurrentTime(ReportCurrentTime reportCurrentTime) {
            this.reportCurrentTime = reportCurrentTime;
        }
    
        @Override
        protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
            reportCurrentTime.printCurrentTime();
        }
    }

    3. Configuring SimpleTrigger in Spring XML

    Configure the job details, trigger timing, and scheduler factory:

    <!-- 1. Job Detail Bean -->
    <bean name="simpleJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.ram.scheduler.SimpleScheduledJob" />
        <property name="jobDataAsMap">
            <map>
                <entry key="reportCurrentTime" value-ref="reportCurrentTime" />
            </map>
        </property>
        <property name="durability" value="true" />
    </bean>
    
    <!-- 2. Simple Trigger Bean -->
    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
        <property name="jobDetail" ref="simpleJobDetail" />
        <property name="startDelay" value="2000" /> <!-- Delay 2 seconds before start -->
        <property name="repeatInterval" value="5000" /> <!-- Repeat every 5 seconds -->
    </bean>
    
    <!-- 3. Scheduler Factory Bean -->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="simpleTrigger" />
            </list>
        </property>
    </bean>

    4. Key Properties Explained

    • startDelay: Time in milliseconds the scheduler waits before the first execution of the job.
    • repeatInterval: Time in milliseconds between consecutive job firings.
    • repeatCount: Specifies the number of times to repeat (optional, defaults to repeating indefinitely).

    5. Running and Testing the Application

    Bootstrap your application by loading the context via ClassPathXmlApplicationContext. Once the context is initialized, the Quartz scheduler starts automatically, delays by the configured initial delay, and periodically prints the timestamp output to the console.


    Related Video Tutorials


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

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

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

    Spring+Quartz Scheduler Integration Example (SimpleTriggerFactoryBean) | 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()));
        }

    }

    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 just need to invoke a method on a specific object -->
        <bean id="simpleJobDetail"
            class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
            <property name="targetObject" ref="reportCurrentTime" />
            <property name="targetMethod" value="printCurrentTime" />
        </bean>

        <!-- Run the job every 2 seconds with initial delay of 1 second -->
        <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>

        <!-- 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="simpleJobDetail" />
                </list>
            </property>
       
            <property name="triggers">
                <list>
                    <ref bean="simpleTrigger" />
                </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 = 09:48:37
    Current time = 09:48:39
    Current time = 09:48:41
    Current time = 09:48:43
    Current time = 09:48:45

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

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

    Bitbucket Link:
    https://bitbucket.org/ramram43210/spring/src/0989e369f77ed192b0b224588ebfcdeb2019a6a2/Spring_2018/SpringDemo_Quartz_SimpleTriggerFactoryBean/?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
  • Tutorials