Backend Development 13 min read

Comprehensive Guide to Creating Job Scheduling Tasks with Quartz, xxl-job, and Spring Boot

This article provides a step‑by‑step tutorial on five different ways to implement Java job scheduling—including raw threads, TimerTask, thread pools, Quartz framework, and Spring @Scheduled—followed by detailed instructions for setting up the xxl‑job admin console, configuring a Spring Boot project, and deploying sample job handlers.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Comprehensive Guide to Creating Job Scheduling Tasks with Quartz, xxl-job, and Spring Boot

The article introduces job scheduling in Java, offering a link to a Quartz expression generator and listing supported frameworks such as xxl‑job, Spring Boot's @Scheduled , and Quartz.

1. Five ways to create job scheduling tasks

1) Using a thread to create a job task

/**
 * TODO  使用线程创建 job 定时任务
 * @author 王松
 */
public class JobThread {
    public static class Demo01 {
        static long count = 0;
        public static void main(String[] args) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(1000);
                            count++;
                            System.out.println(count);
                        } catch (Exception e) {
                            // TODO: handle exception
                        }
                    }
                }
            };
            Thread thread = new Thread(runnable);
            thread.start();
        }
    }
}

2) Using TimerTask to create a job task

/**
 * TODO 使用 TimerTask 创建 job 定时任务
 * @author 王松
 */
public class JobTimerTask {
    static long count = 0;
    public static void main(String[] args) {
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                count++;
                System.out.println(count);
            }
        };
        // Create timer and set interval
        Timer timer = new Timer();
        long delay = 0; // start delay
        long period = 1000; // interval in ms
        timer.scheduleAtFixedRate(timerTask, delay, period);
    }
}

3) Using a thread pool to create a job task

/**
 * TODO 使用线程池创建 job 定时任务
 * @author 王松
 */
public class JobScheduledExecutorService {
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                // task to run goes here
                System.out.println("Hello !!");
            }
        };
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        // first execution delay = 1, repeat interval = 1 second
        service.scheduleAtFixedRate(runnable, 1, 1, TimeUnit.SECONDS);
    }
}

4) Using the Quartz framework

First, add Maven dependencies:

<dependencies>
    <!-- quartz -->
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.2.1</version>
    </dependency>
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz-jobs</artifactId>
        <version>2.2.1</version>
    </dependency>
</dependencies>

Create a job class:

public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("quartz MyJob date:" + System.currentTimeMillis());
    }
}

Create a scheduler starter:

public class JobQuartz {
    public static void main(String[] args) throws SchedulerException {
        SchedulerFactory sf = new StdSchedulerFactory();
        Scheduler scheduler = sf.getScheduler();
        JobDetail jb = JobBuilder.newJob(MyJob.class)
                .withDescription("this is a ram job")
                .withIdentity("ramJob", "ramGroup")
                .build();
        long time = System.currentTimeMillis() + 3 * 1000L;
        Date startTime = new Date(time);
        Trigger t = TriggerBuilder.newTrigger()
                .withDescription("")
                .withIdentity("ramTrigger", "ramTriggerGroup")
                .startAt(startTime)
                .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
                .build();
        scheduler.scheduleJob(jb, t);
        scheduler.start();
    }
}

5) Using Spring Boot's @Scheduled annotation

@Component
@Configuration
@EnableScheduling
public class StaticScheduleTask {
    @Scheduled(cron = "0/5 * * * * ?")
    private void configureTasks() {
        System.err.println("执行静态定时任务时间: " + LocalDateTime.now());
    }
}

2. xxl‑job Admin Console Setup

xxl‑job provides a distributed task scheduler that prevents duplicate execution in a cluster and offers load‑balancing features.

Step 1: Clone the source from GitHub and import it.

Step 2: Execute the provided SQL script xxl-job/doc/db/tables_xxl_job.sql to create the database schema.

Step 3: Modify application.properties in the admin project to set the database connection.

Step 4: Start the admin project with Spring Boot (default URL http://localhost:8080/xxl-job-admin/ , credentials admin / 123456).

3. Building a Spring Boot Project that Registers with xxl‑job

Add the following dependencies to pom.xml :

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.1.1-SNAPSHOT</version>
</dependency>

Configure logging with logback.xml (copy the provided XML).

Set the following properties in application.properties (adjust IP, ports, and paths as needed):

# Server port
server.port=8081
# Logging configuration
logging.config=classpath:logback.xml

# xxl‑job admin address (comma‑separated if multiple)
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin

# Executor configuration
xxl.job.executor.appname=xxl-job-executor-sample
xxl.job.executor.ip=192.168.43.153
xxl.job.executor.port=9999
xxl.job.accessToken=
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
xxl.job.executor.logretentiondays=-1

Create a configuration class XxlJobConfig to instantiate XxlJobSpringExecutor with the above properties:

package xxljob.config;

import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class XxlJobConfig {
    private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);

    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;
    @Value("${xxl.job.executor.appname}")
    private String appName;
    @Value("${xxl.job.executor.ip}")
    private String ip;
    @Value("${xxl.job.executor.port}")
    private int port;
    @Value("${xxl.job.accessToken}")
    private String accessToken;
    @Value("${xxl.job.executor.logpath}")
    private String logPath;
    @Value("${xxl.job.executor.logretentiondays}")
    private int logRetentionDays;

    @Bean(initMethod = "start", destroyMethod = "destroy")
    public XxlJobSpringExecutor xxlJobExecutor() {
        logger.info(">>>>>>>>> xxl-job config init.");
        XxlJobSpringExecutor executor = new XxlJobSpringExecutor();
        executor.setAdminAddresses(adminAddresses);
        executor.setAppName(appName);
        executor.setIp(ip);
        executor.setPort(port);
        executor.setAccessToken(accessToken);
        executor.setLogPath(logPath);
        executor.setLogRetentionDays(logRetentionDays);
        System.err.println(ip + ":" + port);
        return executor;
    }
}

Define a job handler class:

@JobHandler(value="demoJobHandler")
@Component
public class DemoJobHandler extends IJobHandler {
    static int count;
    @Override
    public ReturnT
execute(String param) throws Exception {
        System.out.println("执行job任务" + count++);
        return SUCCESS;
    }
}

In the xxl‑job admin UI, register the executor, create a new job, and set the cron expression (generated at cron.qqe2.com ). The job name corresponds to the @JobHandler value (e.g., demoJobHandler ).

After completing the above steps, the Spring Boot application will successfully register with the xxl‑job admin console and execute scheduled jobs.

JavaSpring Bootxxl-jobcronQuartzJob Schedulingtask executor
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.