最近做东西遇到这样一个问题。
我的CMS文章模块中,文章生成静态页可以有三种选择(1)立刻发布[color=red](2)定时发布[/color](3)不发布。
所遇到的问题就出在[color=red](2)定时发布[/color]这块。因为每天编辑要编写很多文章,也有很多文章要定时发布。我的架构是struts2+spring2.0+hibernate3.1,所以我想用quartz来实现这个定时发布。像这样的情况,用quartz该如何去做。
我看了网上一些quartz的文章。很多都是转载的,我都跑不起来。
[color=red]最好能给一个这方面的具体例子。代码+注释这种就最好了。
我很需要这方面详细的例子,所以希望大家能说得详细些。[/color]
[b]问题补充:[/b]
zhanglinjian 您好!谢谢你的解答!
您的配置cronExpression表达式是写在配置文件里面,我不想把这个写死。用户可以根据javascript日历自动选择发布时间。格式如:2009-08-08 11:30:05
这样的形式,然后把这个时间写在quartz里面,到了这个时间,程序自动去发布,这是针对每一篇文章的。
请问这个该如何去做?
[b]问题补充:[/b]
cats_tiger,谢谢你的帮助。但是我的问题又做了补充,请您看看有没有什么方法来解决我的问题。
这个就优点麻烦了,网上的没一个是正确的。我回头写一篇Blog吧。下面的代码是如何正确的重启:
[code="java"]
@Autowired(required = true)
private ApplicationContext ctx;
/**
@throws ApplicationException 如果CRON无法解析,或原来的任务无法关闭,以及无法启动新任务.
*/
private void restartJobs(String seisCron, String signCron) {
if(StringUtils.isBlank(seisCron) || StringUtils.isBlank(signCron)) {
logger.warn("CRON未设定。");
return;
}
//trim一下,难保数据库里面没有空格
seisCron = seisCron.trim();
signCron = signCron.trim();
//得到两个trigger
CronTrigger seismicCronTrigger = (CronTrigger) ctx.getBean("seismicEmailCronTrigger", CronTrigger.class);
CronTrigger signCronTrigger = (CronTrigger) ctx.getBean("signEmailCronTrigger", CronTrigger.class);
//如果两个频率都没有变,则不必重新启动.
if(seisCron.equals(seismicCronTrigger.getCronExpression()) &&
signCron.equals(signCronTrigger.getCronExpression())) {
logger.info("频率未改变,Quartz不必重新启动.");
return;
}
//得到SchedulerFactoryBean的实例,注意beanName前面的&符号
SchedulerFactoryBean schedulerFactory = (SchedulerFactoryBean) ctx.getBean("&emailSchedulerFactory");
try {
//重新设定trigger
seismicCronTrigger.setCronExpression(seisCron);
signCronTrigger.setCronExpression(signCron);
schedulerFactory.destroy(); //关闭原来的任务
schedulerFactory.afterPropertiesSet(); //启动新的任务
logger.info("前兆和测震邮件发送任务启动成功.");
} catch (ParseException e) {
throw new ApplicationException("Cron表达式解析错误." + e.getMessage());
} catch (SchedulerException e) {
e.printStackTrace();
throw new ApplicationException("关闭定时任务出现异常.");
} catch (Exception e) {
e.printStackTrace();
throw new ApplicationException("启动定时任务出现异常.");
}
}
[/code]
--创建作业---
public class MyJob extends QuartzJobBean {
private boolean flag=false;
@Override
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
// TODO Auto-generated method stub
if(!flag){
flag=true;
//业务逻辑
flag=false;
}
}
}
---创建触发器---调度事务---
<?xml version="1.0" encoding="UTF-8"?>
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
0 0 15 * * ? //可是定时控制
org.ldsj.util.MyJob //包装作业
//如果作业类中有成员变量,可以在这边初始化
这个简单呀,下面的代码是我从项目中提取的,肯定可以执行的。
[code="xml"]
<bean id="seedProJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="seedpathAction"/>
</property>
<property name="targetMethod">
<value>execSeedPro</value>
</property>
<property name="concurrent">
<value>false</value>
</property>
</bean>
<!-- seed程序执行触发器(trigger) -->
<bean id="seedProTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="seedProJobDetail"/>
</property>
<property name="cronExpression">
<value>0 0 0/4 * * ?</value>
</property>
</bean>
<!-- 启动Quartz任务 -->
<bean id="emailSchedulerFactory"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 使用内存存储,否则可能自动装配dataSource -->
<property name="dataSource"><null/></property>
<!-- 系统启动后自动启动任务 -->
<property name="autoStartup" value="true"/>
<!-- 延时20秒启动 -->
<property name="startupDelay" value="20"/>
<property name="triggers">
<list>
<ref local="seedProTrigger"/>
</list>
</property>
</bean>
[/code]
还有一个问题,就是如果服务器重新启动,那么原先设置的cron就都恢复原样了。这个解决起来稍微复杂一些了。需要继承CronTriggerBean,添加一个设置Cron的方法,然后写一个CronExpression的FactoryBean,在这个FactoryBean中读取数据库中的Cron。反正有点麻烦了。
你需要解决3个问题:
1.安全的重启Quartz,这个我已经回答了。
2.启动的时候,从数据库中读取Cron,这个我有方法,但是写起来比较多,打算写blog了,如果急需,我可以简单说说。
3.把时间转换为Cron,这个有点麻烦,我们的做法是给客户几个选项,比如:每隔8小时、每隔1天等等,也可以让客户自己编辑cron表达式,给他一个cron的教程,反正cron也比较简单的。在上面重启quartz的代码中,有cron表达式的验证功能。