一、官网下载压缩包
在上面文件夹下执行对应的数据库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 MainScheduler 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
#============================================================================
# ConfigureJobStore
#============================================================================
#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 voidexecute(JobExecutionContext context)
throws JobExecutionException {
JobDataMapdata = context.getJobDetail().getJobDataMap();
System.out.println("bean:"+data.getString(SRPTING_BEAN_NAME)+"------------method:"+data.getString(SRPTING_METHOD_NAME));
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 {
System.out.println("ContextLoader.getCurrentWebApplicationContext()-----------"+ContextLoader.getCurrentWebApplicationContext());
ObjectownerClass = ContextLoader.getCurrentWebApplicationContext().getBean(owner);
Methodmethod = 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);
// SchedulerFactorysf = 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(Longid) {
try {
SysJobsysJob=sysJobDao.selectByPrimaryKey(id);
Stringname=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(Longid) {
SysJobsysJob=sysJobDao.selectByPrimaryKey(id);
try {
if(sysJob!=null){
//暂停job
scheduler.pauseJob(newJobKey(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(Longid) {
SysJobsysJob=sysJobDao.selectByPrimaryKey(id);
if(sysJob!=null){
//删除job
try {
boolean flag=true;
Stringname=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 StringexecuteQuartz(String beanName, String methodName){
Stringmes="已成功加入!";
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){
Stringmes="成功加入";
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){
Stringmes="成功加入";
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代码
注:用到的是jqueryeasyui插件
http://www.java1234.com/easyui.html
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"
onkeypress="return noNumbers(event)">
</span>
<a href="#" onclick= "javascript:searchuser();" class="btn btn-info"><i class="icon-search"></i> 查询</a>
<shiro:hasPermission name="job:create">
<a href="javascript:void(0);"onclick="addtn()" class="btnbtn-warning" style="margin-left:50px;"><i class="icon-plusicon-white"></i>新增</a>
</shiro:hasPermission>
<shiro:hasPermission name="job:update">
<a href="javascript:void(0);"onclick="bianji()" class="btnbtn-primary" style="margin-left:10px;"><i class="icon-pencil"></i> 修改</a>
</shiro:hasPermission>
<shiro:hasPermission name="job:delete">
<a href="javascript:void(0);"onclick="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="btnbtn-success" onclick= "savedd()"><i class="icon-ok"></i>提交</button>
<button class="btnbtn-danger" onclick= "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"
onkeypress="returnnoNumbers(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"
onkeypress="returnnoNumbers(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"
onkeypress="returnnoNumbers(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"
onkeypress="returnnoNumbers(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"
onfocus="WdatePicker({dateFmt:'yyyy-MM-ddHH: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"
onfocus="WdatePicker({dateFmt:'yyyy-MM-ddHH: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"
onkeypress="returnnoNumbers(event)" maxlength="100">
</td>
</tr>
</table>
</form>
联系客服