一、官网下载压缩包
在上面文件夹下执行对应的数据库sql文件
得到11个数据库表:
二、新建Maven工程
1、在POM里加入如下依赖:
<!-- quartz start -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
<exclusions>
<exclusion>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
<optional>true</optional>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- quartz end -->
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
2、加入quartz.properties文件:
quartz.propertie中内容如下:
#============================================================================
# Configure Main Scheduler Properties DefaultQuartzScheduler
#============================================================================
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.jobStore.misfireThreshold = 60000
#============================================================================
# Configure JobStore
#============================================================================
#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
#org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegate
#org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.MSSQLDelegate
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = true
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.maxMisfiresToHandleAtATime=1
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.myDS.dialect:org.hibernate.dialect.MySQLDialect
org.quartz.dataSource.myDS.driver=com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL=jdbc:mysql://localhost:3306/prisys?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
org.quartz.dataSource.myDS.user=root
org.quartz.dataSource.myDS.password=root
org.quartz.dataSource.myDS.maxConnections=5
org.quartz.dataSource.myDS.validationQuery=SELECT 1
3、执行指定的bean和方法
/**
* 根据bean和方法执行定时任务
* 执行job
*/
@SuppressWarnings("all")
public class SpringJobModel implements Job {
public static String SRPTING_BEAN_NAME = "beanName";
public static String SRPTING_METHOD_NAME = "methodName";
/*
* (non-Javadoc)
*
* @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
*/
public void execute(JobExecutionContext context)
throws JobExecutionException {
JobDataMap data = context.getJobDetail().getJobDataMap();
try {
invokeMethod(data.getString(SRPTING_BEAN_NAME),data.getString(SRPTING_METHOD_NAME), null);
} catch (Exception e) {
e.printStackTrace();
}
}
public void invokeMethod(String owner, String methodName, Object[] args)
throws Exception {
Object ownerClass = ContextLoader.getCurrentWebApplicationContext().getBean(owner);
Method method = ownerClass.getClass().getMethod(methodName, null);
method.invoke(ownerClass, args);
}
}
4、将定时任务写入数据库
A、执行service类
@Service("schedulerService")
public class SchedulerServiceImpl implements SchedulerService {
// //调度器,任务调度的主API
// @Autowired
private Scheduler scheduler;
@Resource
private SysJobDao sysJobDao;
@PostConstruct
public void init() {
try {
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.startDelayed(60);
// SchedulerFactory sf = new StdSchedulerFactory();
// scheduler =sf.getScheduler();
System.out.println("任务调度启动,延时1分钟后开始执行!");
} catch (Exception e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}
}
//一个具体任务的设置,指定了要执行的任务和执行任务 的时间策略(用于定义任务的实例)
// @Autowired
private JobDetail jobDetail;
private Trigger trigger;// 容器中任务调度器
/**
* 运行
*/
@ServiceLog("运行定时任务")
public void createRunJobByJobId(Long id) {
try {
SysJob sysJob=sysJobDao.selectByPrimaryKey(id);
String name=sysJob.getJobName();
boolean flag=true;
if(name==null||sysJob.equals("")){
flag=false;
}else{
flag=scheduler.checkExists(new JobKey(name, sysJob.getId()+""));
}
//不存在则执行
if(!flag){
name=UUID.randomUUID().toString();
sysJob.setJobName(name);
jobDetail =newJob(SpringJobModel.class).withIdentity(name, sysJob.getId()+"").build();
jobDetail.getJobDataMap().put(SpringJobModel.SRPTING_BEAN_NAME, sysJob.getBeanName());
jobDetail.getJobDataMap().put(SpringJobModel.SRPTING_METHOD_NAME, sysJob.getMethodName());
// 复杂 的任务调度
TriggerBuilder<CronTrigger> builder = newTrigger().withIdentity(name, jobDetail.getKey().getGroup())
.withSchedule(cronSchedule(sysJob.getExpression()));
// 若有起始时间,则设置
String startTime=sysJob.getStarttime();
String endTime=sysJob.getEndtime();
if (startTime!=null && !startTime.equals("")) {
builder.startAt(DateUtil.stringToDate(startTime));
}
// 设置终止时间
if (endTime!=null && !endTime.equals("")) {
builder.endAt(DateUtil.stringToDate(endTime));
}
trigger = builder.build();
scheduler.scheduleJob(jobDetail, trigger);
//更新
sysJob.setState(1);//已运行
}else{
//恢复Job任务开始执行
scheduler.resumeJob(new JobKey(name, sysJob.getId()+""));
sysJob.setState(1);//已运行
}
sysJobDao.updateByPrimaryKey(sysJob);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 停止
*/
@Override
@ServiceLog("停止定时任务")
public void createStopJobByJobId(Long id) {
SysJob sysJob=sysJobDao.selectByPrimaryKey(id);
try {
if(sysJob!=null){
//暂停job
scheduler.pauseJob(new JobKey(sysJob.getJobName(), sysJob.getId()+""));
}
} catch (UnableToInterruptJobException e) {
e.printStackTrace();
} catch (SchedulerException e) {
e.printStackTrace();
}
sysJob.setState(2);//已停止
sysJobDao.updateByPrimaryKey(sysJob);
}
/**
* 删除
*/
@Override
@ServiceLog("删除定时任务")
public void deleteByPrimaryKey(Long id) {
SysJob sysJob=sysJobDao.selectByPrimaryKey(id);
if(sysJob!=null){
//删除job
try {
boolean flag=true;
String name=sysJob.getJobName();
if(name==null||sysJob.equals("")){
flag=false;
}else{
//判断是否存在
flag=scheduler.checkExists(new JobKey(name, sysJob.getId()+""));
}
if(flag){
scheduler.deleteJob(new JobKey(name, sysJob.getId()+""));
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
sysJobDao.deleteSysJob(sysJob);
}
}
B、SysJob类
/**
* 意义,目的和功能,以及被用到的地方<br>
*/
private static final long serialVersionUID = -2800683486829288336L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id; //定时器JobKey的group
@Column
private String name; //定时器名称
@Column(name="job_name")
private String jobName; //定时器JobKey的Name
@Column(name="bean_name")
private String beanName;//bean名称
@Column(name="method_name")
private String methodName;//方法名称
@Column
private String expression;// 调度表达式
@Column
private String starttime;// 开始时间
@Column
private String endtime;// 结束时间
@Column
private String remark;//备注
@Column
private String createtime;// 创建时间
@Column
private Integer state=2;// 运行状态:1、运行 2、停止
C、Controller层
注: RequiresPermissions 此注解是 shiro 的权限判断注解,可以去掉
@Resource
private SchedulerService schedulerService;
@RequestMapping(value="/execute")
@ResponseBody
public String executeQuartz(String beanName, String methodName){
String mes="已成功加入!";
try {
schedulerService.runBean(beanName, methodName);
} catch (Exception e) {
mes=e.getMessage();
}
return mes;
}
@RequiresPermissions("job:run")
@RequestMapping(value="/{id}/execute")
@ResponseBody
public String executeQuartz(@PathVariable Long id){
String mes="成功加入";
try {
schedulerService.createRunJobByJobId(id);
} catch (Exception e) {
mes=e.getMessage();
logger.error(mes);
}
return mes;
}
@RequiresPermissions("job:run")
@RequestMapping(value="/{id}/stop")
@ResponseBody
public String stopQuartz(@PathVariable Long id){
String mes="成功加入";
try {
schedulerService.createStopJobByJobId(id);
} catch (Exception e) {
mes=e.getMessage();
logger.error(mes);
}
return mes;
}
@RequiresPermissions("job:delete")
@RequestMapping(value = "/{id}/delete", method = RequestMethod.POST)
@ResponseBody
public String delete(@PathVariable("id") Long id) {
String message="删除成功";
try {
schedulerService.deleteByPrimaryKey(id);
} catch (Exception e) {
message="删除失败";
logger.error(e.getMessage());
}
return message;
}
@RequestMapping("/execute2")
public void executeQuartz2(){
schedulerService.runBean2();
}
三、web页面
1、 效果
新增页面
2、 js代码
注:用到的是jquery easyui插件
Jquery Easyui 官网Java1234官网中文API点击打开链接
var dialogWidth=700;
var dialogHeight=485;
var saveurl="";
/**
* 表格
*/
$('#dg').datagrid( {
width: clientWidth-200,
height: clientHeight-180,
rownumbers : true,
singleSelect : true,
pagination : false,
//pageSize : 20,
fitColumns: true,
url : basePath+'/sysjob/listPage'
});
//主列表查询
function searchuser() {
var username=$('#tb #name').val();
var v="";
if(username!=""){
v+=" and name like '%"+username.trim()+"%' ";
}
$("#dg").datagrid("options").queryParams["param"] =v;
$("#dg").datagrid("reload");
}
//新增
function addtn(){
saveurl=basePath+'/sysjob/create';
$('#dd').dialog({
iconCls:'icon-user',
title: '录入',
width: dialogWidth,
height: dialogHeight,
closed: false,
cache: false,
resizable:true,
href: basePath+'/sysjob/addpage',
modal: true,
onLoad:function(){
}
});
//$('#dd').dialog('refresh', 'addpwk.jsp');
}
function savedd(){
save(saveurl);
}
//编辑
function bianji() {
var row = $('#dg').datagrid('getSelected');
if(row==null){
$.messager.alert('提示信息','请选择一条记录!','info');
return;
}
saveurl=basePath+'/sysjob/update';
$('#dd').dialog({
iconCls:'icon-user',
title: '编辑',
width: dialogWidth,
height: dialogHeight,
closed: false,
cache: false,
resizable:true,
href: basePath+'/sysjob/addpage',
modal: true,
onLoad:function(){
$('#form12').form('load', row);
}
});
//$('#dd').dialog('refresh', 'addpwk.jsp');
}
function save(url) {
$('#form12').form('submit', {
url : url,
onSubmit : function() {
//进行表单验证
//如果返回false阻止提交
var flag = $(this).form('validate');
if (flag) {
showProcess(true, '温馨提示', '正在提交数据...');
}
return flag
},
success : function(data) {
showProcess(false);
if (data=='录入成功'||data=='修改成功') {
$.messager.alert('提示信息','提交成功!','info');
$('#dg').datagrid('reload');
$('#dd').dialog('close');
} else if (data=='1') {
$.messager.alert('提示信息','您输入的bean不存在,请重新输入!','error');
} else{
$.messager.alert('提示信息','提交失败!','error');
}
},
error:function (data){
alert(data);
}
});
}
//删除
function deleteRecord(){
var row = $('#dg').datagrid('getSelected');
if(row==null){
$.messager.alert('提示信息','请选择一条记录!','info');
return;
}
$.messager.confirm('删除记录', '确认删除吗?', function(r){
if (r){
showProcess(true, '温馨提示', '正在提交数据...');
$.post(basePath+'/quartz/'+row.id+'/delete',null,function(json){
showProcess(false);
if(json=="删除成功"){
$.messager.alert('提示信息','删除成功!','info',function () {
$('#dg').datagrid('reload');
});
}else{
$.messager.alert('提示信息','删除失败!','error');
}
});
}
});
}
//启动任务
function yunxing(id){
$.messager.confirm('温馨提示', '确认启动吗?', function(r){
if (r){
showProcess(true, '温馨提示', '正在提交数据...');
$.post(basePath+'/quartz/'+id+'/execute',null,function(json){
showProcess(false);
if(json=="成功加入"){
$.messager.alert('提示信息','启动成功!','info',function () {
$('#dg').datagrid('reload');
});
}else{
$.messager.alert('提示信息','启动失败!','error');
}
});
}
});
}
//停止
function tingzhi(id){
$.messager.confirm('温馨提示', '确认停止吗?', function(r){
if (r){
showProcess(true, '温馨提示', '正在提交数据...');
$.post(basePath+'/quartz/'+id+'/stop',null,function(json){
showProcess(false);
if(json=="成功加入"){
$.messager.alert('提示信息','已成功停止!','info',function () {
$('#dg').datagrid('reload');
});
}else{
$.messager.alert('提示信息','停止失败!','error');
}
});
}
});
}
3、 jsp页面
主页面:
<table id="dg" data-options="toolbar:'#tb'">
<thead>
<tr>
<th data-options="field:'name',width:100" >定时器名称</th>
<th data-options="field:'beanName',width:80,align:'center'" >bean名称</th>
<th data-options="field:'methodName',width:80,align:'center'" >方法名称</th>
<th data-options="field:'expression',width:80,align:'center'" >调度表达式</th>
<th data-options="field:'starttime',width:100,align:'center'" >开始时间</th>
<th data-options="field:'endtime',width:100,align:'center'" >结束时间</th>
<th data-options="field:'state',width:80,align:'center',formatter:stateformatter" >运行状态</th>
<th data-options="field:'remark',width:80" >备注</th>
<shiro:hasPermission name="job:run">
<th data-options="field:'tools',width:120,align:'center',formatter:rowformater" >操作</th>
</shiro:hasPermission>
</tr>
</thead>
</table>
<div id="tb" style="padding: 5px; height: auto;">
<div >
<span class="input-prepend"><span class="add-on">定时器名称:</span>
<input type="text" id="name" style="width:150px;" class="m-wrap" maxlength="20"
οnkeypress="return noNumbers(event)">
</span>
<a href="#" οnclick= "javascript: searchuser();" class="btn btn-info"><i class="icon-search"></i> 查询</a>
<shiro:hasPermission name="job:create">
<a href="javascript:void(0);" οnclick="addtn()" class="btn btn-warning" style="margin-left:50px;"><i class="icon-plus icon-white"></i>新增</a>
</shiro:hasPermission>
<shiro:hasPermission name="job:update">
<a href="javascript:void(0);" οnclick="bianji()" class="btn btn-primary" style="margin-left:10px;"><i class="icon-pencil"></i> 修改</a>
</shiro:hasPermission>
<shiro:hasPermission name="job:delete">
<a href="javascript:void(0);" οnclick="deleteRecord()" class="btn btn-danger" style="margin-left:10px;"><i class="icon-trash "></i> 删除</a>
</shiro:hasPermission>
</div>
<!-- 弹出框开始 -->
<div id="dd" class="easyui-dialog" data-options="buttons: '#dd #dlg-buttons',closed:true">
<div id="dlg-buttons">
<button class="btn btn-success" οnclick= "savedd()"><i class="icon-ok"></i>提交</button>
<button class="btn btn-danger" οnclick= "javascript: $('#dd').dialog('close');"><i class="icon-remove"></i>关闭</button>
</div>
</div>
<!-- 弹出框结束 -->
弹出框页面:
<form action="#" method="post" id="form12">
<table class="table_jjval" style="width:99%;">
<input type="hidden" name="id" id="id"/>
<input type="hidden" name="state" id="state" value="2"/>
<input type="hidden" name="createtime" id="createtime"/>
<tr height="45">
<td style="width:20%;" class="td_left">任务名称:</td>
<td style="width:30%;">
<input style="margin-left:5px;width:90%;" class="easyui-validatebox"
data-options="required:true" missingMessage="请输入任务名称"
type="text" id="name" name="name"
οnkeypress="return noNumbers(event)" maxlength="100" >
</td>
</tr>
<tr height="45">
<td style="width:20%;" class="td_left">bean名称:</td>
<td style="width:30%;">
<input style="margin-left:5px;width:90%;" class="easyui-validatebox"
data-options="required:true" missingMessage="请输入bean名称"
type="text" id="beanName" name="beanName"
οnkeypress="return noNumbers(event)" maxlength="100" >
</td>
</tr>
<tr height="45">
<td style="width:20%;" class="td_left">方法名称:</td>
<td style="width:30%;">
<input style="margin-left:5px;width:90%;" class="easyui-validatebox"
data-options="required:true" missingMessage="请输入方法名称"
type="text" id="methodName" name="methodName"
οnkeypress="return noNumbers(event)" maxlength="100" >
</td>
</tr>
<tr height="45">
<td style="width:20%;" class="td_left">调度表达式:</td>
<td style="width:30%;">
<input style="margin-left:5px;width:90%;" class="easyui-validatebox"
data-options="required:true" missingMessage="请输入调度表达式"
type="text" id="expression" name="expression"
οnkeypress="return noNumbers(event)" maxlength="100" >
</td>
</tr>
<tr height="45">
<td style="width:20%;" class="td_left">开始时间:</td>
<td style="width:30%;">
<input style="margin-left:5px;width:150px;"
type="text" id="starttime" name="starttime"
οnfοcus="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss'})" class="Wdate" maxlength="100" >
</td>
</tr>
<tr height="45">
<td style="width:20%;" class="td_left">结束时间:</td>
<td style="width:30%;">
<input style="margin-left:5px;width:150px"
type="text" id="endtime" name="endtime"
οnfοcus="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss'})" class="Wdate" maxlength="100" >
</td>
</tr>
<tr height="45">
<td style="width:20%;" class="td_left">备注:</td>
<td style="width:30%;">
<input style="margin-left:5px;width:90%;" class="easyui-validatebox"
type="text" id="remark" name="remark"
οnkeypress="return noNumbers(event)" maxlength="100" >
</td>
</tr>
</table>
</form>
例子源代码:点击打开链接