• Spring定时器在SSH框架中的应用


    本课题参考自《Spring in action》。并非应用系统中发生的所有事情都是由用户的动作引起的。有时候,系统自己也需要发起一些动作。例如,集抄系统每天早上六点把抄表数据传送 给营销系统。我们有两种选择:或者是每天由用户手动出发任务,或者让应用系统中按照预定的计划自动执行任务。
    在Spring中有两种流行配置:Java的Timer类和OpenSymphony的Quartz来执行调度任务。下面以给商丘做的接口集抄900到中间库的日冻结数据传输为例:
    1. Java Timer调度器
    首先定义一个定时器任务,继承java.util.TimerTask类实现run方法
    import java.util.TimerTask;
    import xj.service.IJdbc1Service;
    import xj.service.IJdbc2Service;
    public class DayDataTimerTask extends TimerTask{
    private IJdbc2Service jdbc2Service=null;
    private IJdbc1Service jdbc1Service=null;
    public void run(){
    SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println("日冻结转接任务开始时间:"+df.format(Calendar.getInstance().getTime()));
    System.out.println("日冻结转接任务结束时间:"+df.format(Calendar.getInstance().getTime()));
    }

    //通过set方法获取service服务,如果没有该方法,则为null
    public void setJdbc2Service(IJdbc2Service jdbc2Service) {
    this.jdbc2Service = jdbc2Service;
    }

    public void setJdbc1Service(IJdbc1Service jdbc1Service) {
    this.jdbc1Service = jdbc1Service;
    }
    }
    Run()方法定义了当任务运行时该做什么。jdbc1Service,jdbc2Service通过依赖注入的方式提供给DayDataTimerTask。如果该任务中没有service服务的set方法,则取到的该service服务为null。
    其次,在Spring配置文件中声明 dayDataTimerTask:
    <!-- 声明定时器任务 -->
    <bean id="dayDataTimerJob" class="xj.action.DayDataTimerTask">
    <property name="jdbc1Service">
    <ref bean="jdbc1Service"/>
    </property>
    <property name="jdbc2Service">
    <ref bean="jdbc2Service"/>
    </property>
    </bean>
    该声明将DayDataTimerTask放到应用上下文中,并在jdbc1Service、jdbc2Service属性中分别装配jdbc1Service、jdbc2Service。在调度它之前,它不会做任何事情。
    <!-- 调度定时器任务 -->
    <bean id="scheduledDayDataTimerJob" class="org.springframework.scheduling.timer.ScheduledTimerTask">
    <property name="timerTask">
    <ref bean="dayDataTimerJob"/>
    </property>
    <property name="delay">
    <value>3000</value>
    </property>
    <property name="period">
    <value>864000000</value>
    </property>
    </bean>
    属性timerTask告诉ScheduledTimerTask运行哪个TimerTask。再次,该属性装配了指向 scheduledDayDataTimerJob的一个引用,它就是DayDataTimerTask。属性period告诉 ScheduledTimerTask以怎样的频度调用TimerTask的run()方法。该属性以毫秒作为单位,它被设置为864000000,指定 这个任务应该每24小时运行一次。属性delay允许你指定当任务第一次运行之前应该等待多久。在此指定DayDataTimerTask的第一次运行相 对于应用程序的启动时间延迟3秒钟。
    <!-- 启动定时器 -->
    <bean class="org.springframework.scheduling.timer.TimerFactoryBean">
    <property name="scheduledTimerTasks">
    <list>
    <ref bean="scheduledDayDataTimerJob"/>
    </list>
    </property>
    </bean>
    Spring的TimerFactoryBean负责启动定时任务。属性scheduledTimerTasks要求一个需要启动的定时器任务的列表。在此只包含一个指向scheduledDayDataTimerJob的引用。
        Java Timer只能指定任务执行的频度,但无法精确指定它何时运行,这是它的一个局限性。要想精确指定任务的启动时间,就需要使用Quartz[kwɔ:ts]调度器。
    2.Quartz调度器
    Quartz调度器不仅可以定义每隔多少毫秒执行一个工作,还允许你调度一个工作在某个特定的时间或日期执行。
    首先创建一个工作,继承QuartzJobBean类实现executeInternal方法
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.springframework.dao.DataIntegrityViolationException;
    import org.springframework.scheduling.quartz.QuartzJobBean;

    import xj.service.IJdbc1Service;
    import xj.service.IJdbc2Service;
    public class DayDataQuartzTask extends QuartzJobBean{
    private IJdbc2Service jdbc2Service=null;
    private IJdbc1Service jdbc1Service=null;
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException{
    SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println("日冻结转接任务开始时间:"+df.format(Calendar.getInstance().getTime()));
    System.out.println("日冻结转接任务结束时间:"+df.format(Calendar.getInstance().getTime()));
    }

    //通过set方法获取service服务,如果没有该方法,则为null
    public void setJdbc2Service(IJdbc2Service jdbc2Service) {
    this.jdbc2Service = jdbc2Service;
    }

    public void setJdbc1Service(IJdbc1Service jdbc1Service) {
    this.jdbc1Service = jdbc1Service;
    }

    }

    在Spring配置文件中按照以下方式声明这个工作:
    <!-- 定时启动任务 Quartz-->
    <!—声明工作-->
    <bean id="dayDataJob" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass">
    <value>xj.action.DayDataQuartzTask</value>
    </property>
    <property name="jobDataAsMap">
    <map>
    <entry key="jdbc1Service">
    <ref bean="jdbc1Service"/>
    </entry>
    <entry key="jdbc2Service">
    <ref bean="jdbc2Service"/>
    </entry>
    </map>
    </property>
    </bean>
    Quartz的org.quartz.Trigger类描述了何时及以怎样的频度运行一个Quartz工作。Spring提供了两个触发器 SimpleTriggerBean和CronTriggerBean。SimpleTriggerBean与scheduledTimerTasks类 似。指定工作的执行频度,模仿scheduledTimerTasks配置。
    <!-- 调度Simple工作 -->
    <bean id="simpleDayDataJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
    <property name="jobDetail">
    <ref bean="dayDataJob"/>
    </property>
    <property name="startDelay">
    <value>1000</value>
    </property>
    <property name="repeatInterval">
    <value>86400000</value>
    </property>
    </bean>
    <!—调度cron工作-->
    <bean id="dayDataJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail">
    <ref bean="dayDataJob"/>
    </property>
    <property name="cronExpression">
    <value>0 30 2 * * ?</value>
    </property>
    </bean>
    一个cron表达式有6个或7个由空格分隔的时间元素。从左至右,这些元素的定义如下:1、秒(0-59);2、分(0-59);3、小时 (0-23);4、月份中的日期(1-31);5、月份(1-12或JAN-DEC);6、星期中的日期(1-7或SUN-SAT);7、年份 (1970-2099)。
    每一个元素都可以显式地规定一个值(如6),一个区间(如9-12),一个列表(如9,11,13)或一个通配符(如*)。“月份中的日期”和“星期中的日期”这两个元素互斥,应该通过设置一个问号(?)来表明你不想设置的那个字段。

    corn表达式API具体见

    http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger

    我们在此定义该任务在每天凌晨两点半开始启动。
    <!—启动工作-->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
    <list>
    <ref bean="simpleDayDataJobTrigger"/>
    <ref bean="dayDataJobTrigger"/>
    </list>
    </property>
    </bean>
    属性triggers接受一组触发器,在此只装配包含simpleDayDataJobTrigger bea和dayDataJobTrigger bean的一个引用列表。

  • 相关阅读:
    为 WordPress 标签添加 rel="nofollow" 属性
    Discuz X3.2 SEO设置 title 不支持空格的解决方法
    LANMP 如何禁止访问 .htaccess 文件
    Discuz 哪些文件和文件夹需要777权限
    WordPress 模板常用函数
    CSS控制 table 的 cellpadding,cellspacing
    从 Typecho 自定义字段的调用代码看去
    Linux 服务器如何修改 DNS
    Linux 服务器如何禁止 ping 以及开启 ping
    Asp.Net 加载不同项目程序集
  • 原文地址:https://www.cnblogs.com/timelyxyz/p/2507104.html
Copyright © 2020-2023  润新知