JFinal 整合Quartz

本文介绍如何在JFinal框架中整合Quartz实现任务调度功能,包括自定义Quartz插件、配置数据库连接及实现定时任务管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中要加入调度和计划任务等功能,所以选择Quartz调度插件,原先都是在S2SH上整合的。现在项目用JFinal框架,不得不说JFinal框架的定制性真好,可以自己根据项目要求进行修改,并且很节省时间。

    原先当然是先找有没有JFinal的quartz插件,先是找到了JFinal-ext,里面有一个QuartzPlugin,不过因为自己比较喜欢在代码中配置调度,而且项目需求中的调度是实时性的,不是定死的。所以不太适用,所以在JFinal-ext的QuartzPlugin基础上,“抄袭”了一下,下面是我自己改的

【QuartzPlugin】

import java.util.Properties;

import org.quartz.Scheduler;
import org.quartz.impl.StdSchedulerFactory;

import xidian.wwf.ivc.quartz.QuartzFactory;
import xidian.wwf.ivc.utils.PropertiesUtil;

import com.jfinal.plugin.IPlugin;

/**
 * Quartz插件
 * @author WWF
 */
public class QuartzPlugin implements IPlugin{


    /**默认配置文件**/
    private String config = "quartz.properties";

    public QuartzPlugin(){

    }

    public QuartzPlugin(String config){
        this.config = config;
    }

    @Override
    public boolean start() {
        try {
            //加载配置文件
            Properties props = PropertiesUtil.loadPropertyFile(config);
            //实例化
            QuartzFactory.sf = new StdSchedulerFactory(props);
            //获取Scheduler
            Scheduler sched = QuartzFactory.sf.getScheduler();
                sched.start();
                return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public boolean stop() {
        try {
            QuartzFactory.sf.getScheduler().shutdown();
            QuartzFactory.sf = null;
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

}

QuartzFactory是我自己写的一个开始job任务的管理类,如下

import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerKey;

import xidian.wwf.ivc.utils.TimeUtil;

/**
 * QuartzFactory 
 * @author WWF
 */
public class QuartzFactory {

    public static SchedulerFactory sf;

    /**
     * 定时开始任务
     * @param startTime
     * @param id
     * @param name
     * @param group
     * @param jobClass
     */
    public static void startJobOnce(String startTime, int id,String name,String group,Class<? extends Job> jobClass){
        try {
            Scheduler sched = sf.getScheduler();
            // define the job and tie it to our HelloJob class
              JobDetail job = newJob(jobClass)
                  .withIdentity("job_"+name+"_"+id, "group_"+group+"_"+id)
                  .requestRecovery()
                  .build();
              job.getJobDataMap().put(group+"_"+name, id);
              // 定时执行
              SimpleTrigger trigger = (SimpleTrigger) newTrigger()
                  .withIdentity("trigger_"+name+"_"+id, "group_"+group+"_"+id)
                  .startAt(TimeUtil.StringToDate2(startTime))
                  .build();


              sched.scheduleJob(job, trigger);
              sched.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 停止任务
     * @param name
     * @param group
     * @param id
     */
    public static void stopJob(String name,String group,int id){
        try {
            if (sf!=null) {
                Scheduler scheduler = sf.getScheduler();
                TriggerKey triggerKey = TriggerKey.triggerKey("trigger_"+name+"_"+id,"group_"+ group+"_"+id);
                Trigger trigger = scheduler.getTrigger(triggerKey);
                if (trigger!=null) {
                    scheduler.pauseTrigger(triggerKey);
                    scheduler.unscheduleJob(triggerKey);
                    scheduler.deleteJob(trigger.getJobKey());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

因为有时候服务器维护,会关闭tomcat,所以我把调度任务存入到数据库中,可以中断回复,下面是我的quartz.properties配置文件和数据库连接ConnectionProvider

quartz.properties

=============================================

=====
# 配置实例名和id  
#==================================================
org.quartz.scheduler.instanceName = myScheduler
org.quartz.scheduler.instanceId: my
org.quartz.scheduler.skipUpdateCheck: true

#==================================================
# 配置线程池  
#==================================================
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 5
org.quartz.threadPool.threadPriority: 5

#==================================================
# 配置JobStore 
#==================================================
org.quartz.jobStore.misfireThreshold: 600000

org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties=false
org.quartz.jobStore.dataSource=my
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true

#==================================================
# 配置数据库
#==================================================
org.quartz.dataSource.my.connectionProvider.class = QuartzConnectionProvider
QuartzConnectionProvider
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import org.quartz.utils.ConnectionProvider;

import xidian.wwf.ivc.utils.PropertiesUtil;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
import com.jfinal.plugin.druid.DruidPlugin;

/**
 * 自定义QuartzConnectionProvider
 * @author WWF
 */
public class QuartzConnectionProvider implements ConnectionProvider{

    private static final String DB_CONFIG="databaseConfig.properties";
    private DruidPlugin druidPlugin;

    @Override
    public Connection getConnection() throws SQLException {
        return druidPlugin.getDataSource().getConnection();
    }

    @Override
    public void initialize() throws SQLException {
        Properties properties = PropertiesUtil.loadPropertyFile(DB_CONFIG);
        druidPlugin = new DruidPlugin(
                properties.getProperty("jdbcUrl"),
                properties.getProperty("user"),
                properties.getProperty("password"),
                properties.getProperty("jdbcDriverClass"));
        // StatFilter提供JDBC层的统计信息
        druidPlugin.addFilter(new StatFilter());
        // WallFilter的功能是防御SQL注入攻击
        WallFilter wallFilter = new WallFilter();
        wallFilter.setDbType("mysql");
        druidPlugin.addFilter(wallFilter);
        druidPlugin.start();
    }

    @Override
    public void shutdown() throws SQLException {
        druidPlugin.stop();
    } 
}

QuartzConnectionProvider中使用了DruidPlugin,动态加载数据库配置文件,数据库更换只需要修改数据库配置文件即可

最后,新建一个TestJob

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import xidian.wwf.ivc.utils.TimeUtil;

public class TestJob implements Job{

    public TestJob(){
    }

    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        System.out.println("开始时间="+TimeUtil.getTimeAll());
        try {
            //JobDataMap dataMap= arg0.getJobDetail().getJobDataMap();
            System.out.println("哇哈哈");
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("结束时间="+TimeUtil.getTimeAll());
    }   
}

在afterJFinalStart中新建测试任务

//测试quartz

String startTime = "2014-03-09 09:54:00";
QuartzFactory.startJobOnce(startTime, 5, "test", "testgroup", TestJob.class);

到点了就执行TestJob了。大家还可以根据需要,在QuartzFactory中添加间隔定时调度等,因为我项目就一个定点调度,所以基本都是执行一次即可。

写的不好,大家勿喷!

### Spring Boot 整合 Quartz 示例教程 #### 项目依赖设置 为了在Spring Boot应用程序中集成Quartz,需先调整`pom.xml`文件中的依赖项。确保引入了spring-boot-starter-quartz库。 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> ``` 此操作允许开发者利用Spring Boot自动配置功能来简化Quartz的初始化过程[^1]。 #### 配置application.properties/yml 接着,在`application.properties`或`application.yml`内定义必要的属性以适应具体的业务需求: ```yaml spring: quartz: job-store-type: memory # 或者 'jdbc' 如果计划持久化job数据到数据库 wait-time-in-millis-between-scans: 2000L ``` 上述设定指定了存储方式以及扫描间隔时间等参数[^4]。 #### 创建Job类 编写自定义的任务执行逻辑,即创建实现了`org.quartz.Job`接口的新Java类。下面是一个简单的例子展示如何构建这样的组件: ```java import org.quartz.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MyJob implements Job { private static final Logger logger = LoggerFactory.getLogger(MyJob.class); @Override public void execute(JobExecutionContext context) throws JobExecutionException { String jobName = context.getJobDetail().getKey().getName(); logger.info("Executing " + jobName); try { Thread.sleep(5000); // Simulate a long-running task. } catch (InterruptedException e) { throw new JobExecutionException(e); } logger.info(jobName + " has been executed."); } } ``` 这段代码展示了基本的日志记录和模拟长时间运行任务的功能[^3]。 #### 注册Jobs与Triggers 最后一步是在Spring上下文中声明这些jobs及其触发器(triggers)。这可以通过实现`SchedulingConfigurer`接口完成,并重写其中的方法来自定义scheduler工厂bean的行为;也可以直接使用`@Scheduled`注解配合`CronTriggerFactoryBean`实例达到相同效果。这里给出一种基于XML的方式作为示范: ```xml <!-- applicationContext.xml --> <beans xmlns="http://www.springframework.org/schema/beans" ... xsi:schemaLocation=" http://www.springframework.org/schema/beans ..."> <!-- Define the scheduler factory bean --> <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="overwriteExistingJobs" value="true"/> <property name="autoStartup" value="true"/> <!-- Register jobs and triggers here --> <property name="jobDetails"> <list> <ref bean="myJobDetail"/> </list> </property> <property name="triggers"> <list> <ref bean="cronTrigger"/> </list> </property> </bean> <!-- Define your custom job detail --> <bean id="myJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="myService"/> <property name="targetMethod" value="doSomething"/> <property name="concurrent" value="false"/> </bean> <!-- Define cron trigger for scheduling --> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="myJobDetail"/> <property name="cronExpression" value="0 0/5 * * * ?"/> <!-- Every five minutes --> </bean> </beans> ``` 当然,更推荐的做法是采用纯Java配置风格或者借助于`@EnableScheduling`注解结合`@Scheduled(cron=...)`来进行更加简洁明了的操作[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值