JFinal_QuartzPlugin

开发VStation过程中,需要实现任务调度,以前用过Quartz,很不错。现在作为插件,集成到Jfinal中。

思路如下:

1、创建QuartzPlugin ,在启动Jfinal是调用。

2、QuartzPlugin中需要调度的Job通过 Job.properties文件定义,支持多个Job定义。通过反射方式,进行调用。

3、每个Job的cron都可设定,且可控制单个Job是否运行

以上实现后,基本可以满足简单的调度工作。

有待优化地方:

1、支持多个scheduler方式

2、支持数据库方式缓存Job内容

------------------------------

代码如下:

/**
Quartz Pojo
@author  作者 左浩(James )E-mail: 25708164@qq.com  
@date 创建时间:2016年12月27日 下午6:16:32 
@version 1.0  
@since  
@return  
 */
package com.vstation.plugins.quartzPlugin;

public class Quartz {
private String propFile;
private String jobsFile;
private boolean isEnableRun;

public String getPropFile() {
return propFile;
}

public void setPropFile(String propFile) {
this.propFile = propFile;
}


public String getJobsFile() {
return jobsFile;
}

public void setJobsFile(String jobsFile) {
this.jobsFile = jobsFile;
}

public boolean isEnableRun() {
return isEnableRun;
}

public void setEnableRun(boolean isEnableRun) {
this.isEnableRun = isEnableRun;
}
}



/**
Quartz Job Pojo
@author  作者 左浩(James) E-mail: 25708164@qq.com  
@date 创建时间:2016年12月27日 下午6:04:33 
@version 1.0  
@since  
@return  
 */
package com.vstation.plugins.quartzPlugin;

public class QuartzJob {
private String className;
private String cron;
private String jobName;
private String groupName;
private boolean run;

public String getClassName() {
return className;
}

public void setClassName(String className) {
this.className = className;
}

public String getCron() {
return cron;
}

public void setCron(String cron) {
this.cron = cron;
}

public String getJobName() {
return jobName;
}

public void setJobName(String jobName) {
this.jobName = jobName;
}

public String getGroupName() {
return groupName;
}

public void setGroupName(String groupName) {
this.groupName = groupName;
}

public boolean isRun() {
return run;
}

public void setRun(boolean run) {
this.run = run;
}

}
/**
Quartz Plugins 
@author  作者 左浩(James) E-mail: 25708164@qq.com  
@date 创建时间:2016年12月27日 下午5:42:46 
@version 1.0  
@since  
@return  
 */
package com.vstation.plugins.quartzPlugin;

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

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SchedulerMetaData;
import org.quartz.impl.StdSchedulerFactory;

import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.IPlugin;
import com.vstation.controller.UserController;

public class QuartzPlugin implements IPlugin {
	private static Logger log = Logger.getLogger(UserController.class);
//	private String propertiesFile = "quartz.properties";
	private String jobsFile = "jobs.properties";
//	private boolean isEnableRun = false;
	private List<String> jobNameList = new ArrayList<String>();													//Job 名称清单
	private Map<String, QuartzJob> JobsMap = new HashMap<String, QuartzJob>();				//Job 对象Map
	private SchedulerFactory sf;
	private Scheduler sched;

	public QuartzPlugin(Quartz q) {
//		this.propertiesFile = q.getPropFile();
		this.jobsFile = q.getJobsFile();
//		this.isEnableRun = q.isEnableRun();
		init();
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean start() {
		// TODO Auto-generated method stub
		log.info("---------- QuartzPlugin start begin--------------");
		try {
			 sf = new StdSchedulerFactory();
			 sched = sf.getScheduler();
			
			for(int i=0, length = jobNameList.size(); i<length;i++){
				String jobName = jobNameList.get(i);
				QuartzJob jobObj = JobsMap.get( jobName);
				boolean isRun = jobObj.isRun();
				
				if(isRun){
					Class<? extends Job> jobClass1;
					jobClass1 = (Class<? extends Job>) Class.forName(jobObj
							.getClassName());
					
					JobDetail job = newJob(jobClass1)
							.withIdentity(jobName, jobObj.getGroupName()).build();
					
					CronTrigger trigger = newTrigger()
							.withIdentity("trigger1", jobObj.getGroupName())
							.withSchedule(cronSchedule(jobObj.getCron())).build();
					
					sched.scheduleJob(job, trigger);
					log.info("add "+jobName +" to quartz schedule ");
				}else{
					log.info(jobName +" run  is "+ isRun);
				}
			}
			sched.start();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			log.error(e.toString());
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			log.error(e.toString());
		}
		log.info("---------- QuartzPlugin start end --------------");
		return true;
	}


	@Override
	public boolean stop() {
		log.info("---------- QuartzPlugin stop begin --------------");
		try {
			sched.shutdown(true);
			SchedulerMetaData metaData = sched.getMetaData();
			log.info("Executed " + metaData.getNumberOfJobsExecuted()+ " jobs.");
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			log.error(e.toString());
		}
		log.info("---------- QuartzPlugin stop end --------------");
		return false;
	}

	private boolean init() {
		log.info("----------init Quartz Jobs begin -------------");
		boolean result = false;
//		Prop prop = PropKit.use(propertiesFile);
		Prop jobProp = PropKit.use(jobsFile);
		Enumeration<Object> e = jobProp.getProperties().keys();
		
		while (e.hasMoreElements()) {
			String key = (String) e.nextElement();
			if (key.indexOf("job.name")==0) {
				String jobName = jobProp.get(key);
				jobNameList.add(jobName);	
				
				QuartzJob job = new QuartzJob();
				job.setClassName(jobProp.get(jobName + ".class"));
				job.setCron(jobProp.get(jobName + ".cron"));
				job.setGroupName(jobProp.get(jobName + ".group"));
				job.setRun(jobProp.getBoolean(jobName+".run"));
				JobsMap.put(jobName, job);	
				log.info("job.name."+jobName+" put to map");
			}else{
				continue;
			}
		}
		log.info("----------init Quartz Jobs end   -------------");
		return result;
	}

}
Jfinal Config 中调用代码
      /**---------Quartz 插件-----------**/
        Quartz q = new Quartz();
        q.setJobsFile("jobs.properties");
        QuartzPlugin quartzPlugin = new  QuartzPlugin(q);
        me.add(quartzPlugin);


quartz.properties 文件

org.quartz.scheduler.instanceName=VstationScheduler
org.quartz.scheduler.instanceId=AUTO

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 20
org.quartz.threadPool.threadPriority = 9
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
#org.quartz.jobStore.class=org.quartz.simpl.JDBCJobStore
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true


jobs.properties 文件

####quartz 配置类 ###
#author 左浩(James)
#Email 25708164@qq.com
#Date 2016-12-26
#规则说明: 
#1、以job.name 开头,多个job.name 表示有多个任务
#2、以job.name 的value 作为每个任务的后续配置key


#--------------信息发送Jobs begin----------------#
job.name.msg=msgSender
msgSender.class=com.vstation.quartz.jobs.msgSendJob
msgSender.run=false
msgSender.group=msgsender
msgSender.cron=* * * * *
#--------------信息发送Jobs end   ----------------#

#--------------日志收集Jobs begin----------------#
job.name.log=LogWriter
LogWriter.class=com.vstation.jobs.LogJob
LogWriter.run=true
LogWrite.group=logwrite
LogWriter.cron=0/5 * * * * ?
#--------------日志收集Jobs end   ----------------#