derpvail
2009-08-05 00:45
浏览 196
已采纳

关于spring中的quartz应用

最近做东西遇到这样一个问题。
我的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,谢谢你的帮助。但是我的问题又做了补充,请您看看有没有什么方法来解决我的问题。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

5条回答 默认 最新

  • catstiger 2009-08-05 13:11
    已采纳

    这个就优点麻烦了,网上的没一个是正确的。我回头写一篇Blog吧。下面的代码是如何正确的重启:

    [code="java"]
    @Autowired(required = true)
    private ApplicationContext ctx;

    /**

    • 两个任务中的一个cron改变,则重新启动Quartz任务。
    • @param seisCron CRON1
    • @param signCron CRON2
    • @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]

    点赞 打赏 评论
  • zhanglinjian21 2009-08-05 01:21

    --创建作业---
    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 //包装作业




    //如果作业类中有成员变量,可以在这边初始化



    点赞 打赏 评论
  • catstiger 2009-08-05 12:19

    这个简单呀,下面的代码是我从项目中提取的,肯定可以执行的。
    [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]

    点赞 打赏 评论
  • catstiger 2009-08-05 13:18

    还有一个问题,就是如果服务器重新启动,那么原先设置的cron就都恢复原样了。这个解决起来稍微复杂一些了。需要继承CronTriggerBean,添加一个设置Cron的方法,然后写一个CronExpression的FactoryBean,在这个FactoryBean中读取数据库中的Cron。反正有点麻烦了。

    点赞 打赏 评论
  • catstiger 2009-08-05 13:24

    你需要解决3个问题:
    1.安全的重启Quartz,这个我已经回答了。
    2.启动的时候,从数据库中读取Cron,这个我有方法,但是写起来比较多,打算写blog了,如果急需,我可以简单说说。
    3.把时间转换为Cron,这个有点麻烦,我们的做法是给客户几个选项,比如:每隔8小时、每隔1天等等,也可以让客户自己编辑cron表达式,给他一个cron的教程,反正cron也比较简单的。在上面重启quartz的代码中,有cron表达式的验证功能。

    点赞 打赏 评论

相关推荐 更多相似问题