码迷,mamicode.com
首页 > 编程语言 > 详细

spring-boot-quartz, 依赖spring-boot-parent

时间:2016-10-25 01:50:06      阅读:357      评论:0      收藏:0      [点我收藏+]

标签:方便   code   hub   tailf   rem   对象   arraylist   copy   属性   

spring-boot-quartz, 依赖spring-boot-parent

技术分享

application.properties

# IDENTITY (ContextIdApplicationContextInitializer)
spring.application.index=WebQuartz.v1.1
spring.application.name=WebQuartz

#Server
server.port=80
server.jsp-servlet.class-name=org.apache.jasper.servlet.JspServlet

security.basic.enabled=false
management.security.enabled=false

#MVC
spring.mvc.view.prefix=/WEB-INF/views/
spring.resources.static-locations=classpath:/static/

security.basic.enabled=false
management.security.enabled=false

#LOG
logging.config=classpath:log4j2.xml

configuration

@Configuration
public class QuartzConfig {

    @Bean
    public Scheduler scheduler() throws IOException, SchedulerException {
        SchedulerFactory schedulerFactory = new StdSchedulerFactory(quartzProperties());
        Scheduler scheduler = schedulerFactory.getScheduler();
        scheduler.start();
        return scheduler;
    }

    /**
     * 设置quartz属性
     * @throws IOException
     * 2016年10月8日下午2:39:05
     */
    public Properties quartzProperties() throws IOException {
        Properties prop = new Properties();
        prop.put("quartz.scheduler.instanceName", "ServerScheduler");
        prop.put("org.quartz.scheduler.instanceId", "AUTO");
        prop.put("org.quartz.scheduler.skipUpdateCheck", "true");
        prop.put("org.quartz.scheduler.instanceId", "NON_CLUSTERED");
        prop.put("org.quartz.scheduler.jobFactory.class", "org.quartz.simpl.SimpleJobFactory");
        prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
        prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate");
        prop.put("org.quartz.jobStore.dataSource", "quartzDataSource");
        prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
        prop.put("org.quartz.jobStore.isClustered", "true");
        prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        prop.put("org.quartz.threadPool.threadCount", "5");

        prop.put("org.quartz.dataSource.quartzDataSource.driver", "com.mysql.jdbc.Driver");
        prop.put("org.quartz.dataSource.quartzDataSource.URL", "jdbc:mysql://localhost:3306/demo-schema");
        prop.put("org.quartz.dataSource.quartzDataSource.user", "root");
        prop.put("org.quartz.dataSource.quartzDataSource.password", "123456");
        prop.put("org.quartz.dataSource.quartzDataSource.maxConnections", "10");
        return prop;
    }
}

JS

@Service
public class TaskServiceImpl {
    private Logger logger = LogManager.getLogger(getClass());
    @Autowired
    private Scheduler scheduler;

    /**
     * 所有任务列表
     * 2016年10月9日上午11:16:59
     */
    public List<TaskInfo> list(){
        List<TaskInfo> list = new ArrayList<>();

        try {
            for(String groupJob: scheduler.getJobGroupNames()){
                for(JobKey jobKey: scheduler.getJobKeys(GroupMatcher.<JobKey>groupEquals(groupJob))){
                    List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                    for (Trigger trigger: triggers) {
                        Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                        JobDetail jobDetail = scheduler.getJobDetail(jobKey);

                        String cronExpression = "", createTime = "";

                        if (trigger instanceof CronTrigger) {
                            CronTrigger cronTrigger = (CronTrigger) trigger;
                            cronExpression = cronTrigger.getCronExpression();
                            createTime = cronTrigger.getDescription();
                        }
                        TaskInfo info = new TaskInfo();
                        info.setJobName(jobKey.getName());
                        info.setJobGroup(jobKey.getGroup());
                        info.setJobDescription(jobDetail.getDescription());
                        info.setJobStatus(triggerState.name());
                        info.setCronExpression(cronExpression);
                        info.setCreateTime(createTime);
                        list.add(info);
                    }                   
                }
            }           
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

        return list;
    }

    /**
     * 保存定时任务
     * @param info
     * 2016年10月9日上午11:30:40
     */
    @SuppressWarnings("unchecked")
    public void addJob(TaskInfo info) {
        String jobName = info.getJobName(), 
               jobGroup = info.getJobGroup(), 
               cronExpression = info.getCronExpression(),
               jobDescription = info.getJobDescription(),
               createTime = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        try {
            if (checkExists(jobName, jobGroup)) {
                logger.info("===> AddJob fail, job already exist, jobGroup:{}, jobName:{}", jobGroup, jobName);
                throw new ServiceException(String.format("Job已经存在, jobName:{%s},jobGroup:{%s}", jobName, jobGroup));
            }

            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
            JobKey jobKey = JobKey.jobKey(jobName, jobGroup);

            CronScheduleBuilder schedBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withDescription(createTime).withSchedule(schedBuilder).build();


            Class<? extends Job> clazz = (Class<? extends Job>)Class.forName(jobName);
            JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(jobKey).withDescription(jobDescription).build();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException | ClassNotFoundException e) {
            throw new ServiceException("类名不存在或执行表达式错误");
        }
    }

    /**
     * 修改定时任务
     * @param info
     * 2016年10月9日下午2:20:07
     */
    public void edit(TaskInfo info) {
        String jobName = info.getJobName(), 
               jobGroup = info.getJobGroup(), 
               cronExpression = info.getCronExpression(),
               jobDescription = info.getJobDescription(),
               createTime = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        try {
            if (!checkExists(jobName, jobGroup)) {
                throw new ServiceException(String.format("Job不存在, jobName:{%s},jobGroup:{%s}", jobName, jobGroup));
            }
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
            JobKey jobKey = new JobKey(jobName, jobGroup);
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withDescription(createTime).withSchedule(cronScheduleBuilder).build();

            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            jobDetail.getJobBuilder().withDescription(jobDescription);
            HashSet<Trigger> triggerSet = new HashSet<>();
            triggerSet.add(cronTrigger);

            scheduler.scheduleJob(jobDetail, triggerSet, true);
        } catch (SchedulerException e) {
            throw new ServiceException("类名不存在或执行表达式错误");
        }
    }

    /**
     * 删除定时任务
     * @param jobName
     * @param jobGroup
     * 2016年10月9日下午1:51:12
     */
    public void delete(String jobName, String jobGroup){
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        try {
            if (checkExists(jobName, jobGroup)) {
                scheduler.pauseTrigger(triggerKey);
                scheduler.unscheduleJob(triggerKey);
                logger.info("===> delete, triggerKey:{}", triggerKey);
            }
        } catch (SchedulerException e) {
            throw new ServiceException(e.getMessage());
        }
    }

    /**
     * 验证是否存在
     * @param jobName
     * @param jobGroup
     * @throws SchedulerException
     * 2016年10月8日下午5:30:43
     */
    private boolean checkExists(String jobName, String jobGroup) throws SchedulerException{
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        return scheduler.checkExists(triggerKey);
    }
}

 

https://github.com/leelance/spring-boot-all/tree/master/spring-boot-quartz

 

由于项目使用spring-boot框架,其框架是为了实现零配置文件去做开发的理念,所以在项目中集成Quartz任务调度并不像spring那样直接配置XML.

首先项目需要用到的jar包:

 

[html] view plain copy
 
  1. <dependency>  
  2.             <groupId>org.springframework</groupId>  
  3.             <artifactId>spring-context-support</artifactId>  
  4.             <version>4.1.6.RELEASE</version>  
  5.         </dependency>  
  6. <dependency>  
  7.             <groupId>org.quartz-scheduler</groupId>  
  8.             <artifactId>quartz</artifactId>  
  9.             <version>2.2.1</version>  
  10.         </dependency>  


交给spring管理的bean,代码如下

 

 

[java] view plain copy
 
  1. package com.xxx;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import org.mybatis.spring.annotation.MapperScan;  
  6. import org.quartz.JobDetail;  
  7. import org.quartz.Trigger;  
  8. import org.quartz.spi.JobFactory;  
  9. import org.springframework.beans.factory.annotation.Qualifier;  
  10. import org.springframework.beans.factory.annotation.Value;  
  11. import org.springframework.boot.autoconfigure.EnableAutoConfiguration;  
  12. import org.springframework.context.ApplicationContext;  
  13. import org.springframework.context.annotation.Bean;  
  14. import org.springframework.context.annotation.ComponentScan;  
  15. import org.springframework.context.annotation.ComponentScan.Filter;  
  16. import org.springframework.context.annotation.Configuration;  
  17. import org.springframework.context.annotation.FilterType;  
  18. import org.springframework.scheduling.annotation.EnableScheduling;  
  19. import org.springframework.scheduling.quartz.CronTriggerFactoryBean;  
  20. import org.springframework.scheduling.quartz.JobDetailFactoryBean;  
  21. import org.springframework.scheduling.quartz.SchedulerFactoryBean;  
  22. import org.springframework.test.context.ContextConfiguration;  
  23. import org.springframework.test.context.web.WebAppConfiguration;  
  24. import org.springframework.transaction.annotation.EnableTransactionManagement;  
  25.   
  26. import com.xxx.base.BaseWebAppConfig;  
  27. import com.xxx.cars.quartz.AutowiringSpringBeanJobFactory;  
  28. import com.xxx.cars.quartz.SampleJob;  
  29.   
  30. @Configuration  
  31. @EnableScheduling  
  32. @ContextConfiguration  
  33. @WebAppConfiguration  
  34. @ComponentScan(basePackages = { "com.xxx" }, excludeFilters = { @Filter(type = FilterType.ANNOTATION, value = Configuration.class) })  
  35. @MapperScan("com.xxx.cars.persistence")  
  36. @EnableTransactionManagement  
  37. @EnableAutoConfiguration  
  38. public class WebAppConfig extends BaseWebAppConfig {  
  39.     /** 
  40.      * 配置拦截器 
  41.      *  
  42.      * @author jodie 
  43.      * @param registry 
  44.      */  
  45. //  public void addInterceptors(InterceptorRegistry registry) {  
  46. //      registry.addInterceptor(new UserSecurityInterceptor()).addPathPatterns(  
  47. //              "/**");  
  48. //  }  
  49.       
  50.      @Bean  
  51.         public JobFactory jobFactory(ApplicationContext applicationContext) {  
  52.             AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();  
  53.             jobFactory.setApplicationContext(applicationContext);  
  54.             return jobFactory;  
  55.         }  
  56.   
  57.         /**调度工厂bean  
  58.          * @param jobFactory  
  59.          * @param sampleJobTrigger  
  60.          * @return  
  61.          * @author LDX  
  62.          * @throws IOException  
  63.          */  
  64.         @Bean  
  65.         public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory,  
  66.                                                          @Qualifier("cronJobTrigger") Trigger cronJobTrigger) throws IOException {  
  67.             SchedulerFactoryBean factory = new SchedulerFactoryBean();  
  68.             // this allows to update triggers in DB when updating settings in config file:  
  69.             //用于quartz集群,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了  
  70.             factory.setOverwriteExistingJobs(true);  
  71.           //用于quartz集群,加载quartz数据源  
  72. //          factory.setDataSource(dataSource);  
  73.             factory.setJobFactory(jobFactory);  
  74.             //QuartzScheduler 延时启动,应用启动完20秒后 QuartzScheduler 再启动  
  75.             factory.setStartupDelay(20);  
  76.           //用于quartz集群,加载quartz数据源配置  
  77. //          factory.setQuartzProperties(quartzProperties());  
  78.             //注册触发器  
  79.             factory.setTriggers(cronJobTrigger);  
  80.   
  81.             return factory;  
  82.         }  
  83.   
  84.         /**加载quartz数据源配置,quartz集群时用到 
  85.          * @return 
  86.          * @author LDX 
  87.          * @throws IOException 
  88.          */  
  89. //      @Bean  
  90. //      public Properties quartzProperties() throws IOException {  
  91. //          PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();  
  92. //          propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));  
  93. //          propertiesFactoryBean.afterPropertiesSet();  
  94. //          return propertiesFactoryBean.getObject();  
  95. //      }  
  96.   
  97.         /**加载触发器 
  98.          * @author LDX 
  99.          * @return 
  100.          */  
  101.         @Bean  
  102.         public JobDetailFactoryBean sampleJobDetail() {  
  103.             return createJobDetail(ApplicationJob.class);  
  104.         }  
  105.   
  106.         /**加载定时器 
  107.          * @param jobDetail 
  108.          * @param frequency 
  109.          * @author LDX 
  110.          * @return 
  111.          */  
  112.         @Bean(name = "cronJobTrigger")  
  113.         public CronTriggerFactoryBean sampleJobTrigger(@Qualifier("sampleJobDetail") JobDetail jobDetail,  
  114.                                                          @Value("${samplejob.frequency}") long frequency) {  
  115.             return createTrigger(jobDetail, frequency);  
  116.         }  
  117.   
  118.         /**创建触发器工厂 
  119.          * @param jobClass 
  120.          * @author LDX 
  121.          * @return 
  122.          */  
  123.         private static JobDetailFactoryBean createJobDetail(Class jobClass) {  
  124.             JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();  
  125.             factoryBean.setJobClass(jobClass);  
  126.             factoryBean.setDurability(true);  
  127.             return factoryBean;  
  128.         }  
  129.   
  130.         /**创建一个以频率为触发节点,以毫秒为单位,可以指定每隔x秒执行任务 
  131.          * @param jobDetail 
  132.          * @param pollFrequencyMs 
  133.          * @author LDX 
  134.          * @return 
  135.           
  136.         private static SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail, long pollFrequencyMs) { 
  137.             SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean(); 
  138.             factoryBean.setJobDetail(jobDetail); 
  139.             factoryBean.setStartDelay(0L); 
  140.             factoryBean.setRepeatInterval(pollFrequencyMs); 
  141.             factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY); 
  142.             // in case of misfire, ignore all missed triggers and continue : 
  143.             factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT); 
  144.             return factoryBean; 
  145.         }*/  
  146.           
  147.         /**创建定时器工厂 
  148.          * @param jobDetail 
  149.          * @param pollFrequencyMs 
  150.          * @author LDX 
  151.          * @return 
  152.          */  
  153.         private static CronTriggerFactoryBean createTrigger(JobDetail jobDetail, long pollFrequencyMs) {  
  154.             CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();  
  155.             factoryBean.setJobDetail(jobDetail);  
  156.             factoryBean.setStartDelay(0L);  
  157.             factoryBean.setCronExpression ("0/5 * * * * ? ");//每5秒执行一次  
  158.             return factoryBean;  
  159.         }  
  160.           
[java] view plain copy
 
  1. package com.xxx.cars.quartz;  
  2.   
  3. import org.quartz.spi.TriggerFiredBundle;  
  4. import org.springframework.beans.factory.config.AutowireCapableBeanFactory;  
  5. import org.springframework.context.ApplicationContext;  
  6. import org.springframework.context.ApplicationContextAware;  
  7. import org.springframework.scheduling.quartz.SpringBeanJobFactory;  
  8.   
  9. public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory  
  10.         implements ApplicationContextAware {  
  11.   
  12.     private transient AutowireCapableBeanFactory beanFactory;  
  13.   
  14.     @Override  
  15.     public void setApplicationContext(final ApplicationContext context) {  
  16.         beanFactory = context.getAutowireCapableBeanFactory();  
  17.     }  
  18.   
  19.     @Override  
  20.     protected Object createJobInstance(final TriggerFiredBundle bundle)  
  21.             throws Exception {  
  22.         final Object job = super.createJobInstance(bundle);  
  23.         beanFactory.autowireBean(job);  
  24.         return job;  
  25.     }  
  26. }  


任务调度触发器类

 

 

[java] view plain copy
 
  1. package com.xxx.cars.quartz;  
  2.   
  3. import javax.annotation.Resource;  
  4.   
  5. import org.quartz.Job;  
  6. import org.quartz.JobExecutionContext;  
  7. import org.quartz.JobExecutionException;  
  8.   
  9. import com.cbkj.sz.cars.entity.ApplicationInfo;  
  10. import com.cbkj.sz.cars.service.ApplicationInfoService;  
  11. import org.springframework.scheduling.quartz.QuartzJobBean;  
  12.   
  13. /** 
  14.  * @author LDX 
  15.  * 
  16.  */  
  17. public class ApplicationJob implements Job{  
  18.   
  19.     @Resource  
  20.     private ApplicationInfoService<ApplicationInfo> applicationInfoService;  
  21.   
  22.     @Override  
  23.     public void execute(JobExecutionContext arg0) throws JobExecutionException {  
  24.         try {  
  25.             applicationInfoService.quartz_text();  
  26.         } catch (Exception e) {  
  27.             e.printStackTrace();  
  28.         }     
  29.           
  30.     }  
  31.   
  32.       
  33.       
  34.       
  35. }   
[java] view plain copy
 
  1. <pre name="code" class="java">@Value("${samplejob.frequency}")  

 


这个配置系统配置文件中,本项目使用的是yml配置文件,示例如下技术分享

 

 

运行项目,任务调度完美运行......

http://blog.csdn.net/u010623907/article/details/46684515

 

这篇文章参照了以下三篇文章:

http://www.itnose.net/detail/6149670.html

http://blog.csdn.net/u010623907/article/details/46684515

http://lavasoft.blog.51cto.com/62575/181907/

 

首先明白Quartz核心概念会变得很容易理解配置.

 

 

1、Job
表示一个工作,要执行的具体内容。此接口中只有一个方法
void execute(JobExecutionContext context)
 
2、JobDetail
JobDetail表示一个具体的可执行的调度程序,Job是这个可执行程调度程序所要执行的内容,另外JobDetail还包含了这个任务调度的方案和策略。
 
3、Trigger代表一个调度参数的配置,什么时候去调。
 
4、Scheduler代表一个调度容器,一个调度容器中可以注册多个JobDetail和Trigger。当Trigger与JobDetail组合,就可以被Scheduler容器调度了。

以下是主要的配置类
[java] view plain copy
 
  1. @Configuration  
  2. public class SchedledConfiguration {  
  3.   
  4.   
  5.     @Bean(name = "detailFactoryBean")  
  6.     public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduledTasks scheduledTasks){  
  7.         MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean ();  
  8.         //这儿设置对应的Job对象  
  9.         bean.setTargetObject (scheduledTasks);  
  10.         //这儿设置对应的方法名  与执行具体任务调度类中的方法名对应  
  11.         bean.setTargetMethod ("work");  
  12.         bean.setConcurrent (false);  
  13.         return bean;  
  14.     }  
  15.   
  16.     @Bean(name = "cronTriggerBean")  
  17.     public CronTriggerFactoryBean cronTriggerBean(MethodInvokingJobDetailFactoryBean detailFactoryBean){  
  18.         CronTriggerFactoryBean trigger = new CronTriggerFactoryBean ();  
  19.         trigger.setJobDetail (detailFactoryBean.getObject ());  
  20.         try {  
  21.             trigger.setCronExpression ("0/5 * * ? * *");//每5秒执行一次  
  22.         } catch (ParseException e) {  
  23.             e.printStackTrace ();  
  24.         }  
  25.         return trigger;  
  26.   
  27.     }  
  28.   
  29.     @Bean  
  30.     public SchedulerFactoryBean schedulerFactory(CronTriggerFactoryBean cronTriggerBean){  
  31.         SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean ();  
  32.         schedulerFactory.setTriggers(cronTriggerBean.getObject());  
  33.         return schedulerFactory;  
  34.     }  
  35. }  

以下是具体执行调度任务的类
[java] view plain copy
 
  1. @Component  
  2. @Configurable  
  3. @EnableScheduling  
  4. public class ScheduledTasks {  
  5.   
  6.     public void work(){  
  7.           //这儿插入具体的调度任务  
  8.     }  
  9. }  

总结:
    总的说来,quartz的配置类主要就是以下三点.
    (1)JobDetail(MethodInvokingJobDetailFactoryBean)的配置需要Job这个参数(具体执行调度任务的类,也就是例子中的ScheduledTasks ).
 
    (2)Trigger(CronTriggerFactoryBean)的配置需要JobDetail这个参数.同时需要配置cron表达式,这个下面谈.
 
    (3)Scheduler(SchedulerFactoryBean)的配置需要Trigger这个参数.
 
PS:
    cron表达式具体的东西可以网上搜,很多的,在这只说我碰到的一个问题,cron表达式的第4位和第6位有一位必须是?
 
    错误示例:
        0 0 0 * * *      这个期望表达的意思是每天0点调度一个任务,但是这样写会报错.
        0 0 0 ? * *或者0 0 0 * * ?   这两种表达都是每天0点调度一个任务,这样写才是正确的

 

http://blog.csdn.net/u012432826/article/details/50827260

在做项目时有时候会有定时器任务的功能,比如某某时间应该做什么,多少秒应该怎么样之类的。

spring支持多种定时任务的实现。我们来介绍下使用spring的定时器和使用quartz定时器

  1.我们使用spring-boot作为基础框架,其理念为零配置文件,所有的配置都是基于注解和暴露bean的方式。

  2.使用spring的定时器:

    spring自带支持定时器的任务实现。其可通过简单配置来使用到简单的定时任务。

技术分享
@Component
@Configurable
@EnableScheduling
public class ScheduledTasks{

    @Scheduled(fixedRate = 1000 * 30)
    public void reportCurrentTime(){
        System.out.println ("Scheduling Tasks Examples: The time is now " + dateFormat ().format (new Date ()));
    }

    //每1分钟执行一次
    @Scheduled(cron = "0 */1 *  * * * ")
    public void reportCurrentByCron(){
        System.out.println ("Scheduling Tasks Examples By Cron: The time is now " + dateFormat ().format (new Date ()));
    }

    private SimpleDateFormat dateFormat(){
        return new SimpleDateFormat ("HH:mm:ss");
    }
    
}
技术分享

没了,没错,使用spring的定时任务就这么简单,其中有几个比较重要的注解:

   @EnableScheduling:标注启动定时任务。

@Scheduled(fixedRate = 1000 * 30) 定义某个定时任务。

  3.使用quartz实现定时任务。
    Quartz设计者做了一个设计选择来从调度分离开作业。Quartz中的触发器用来告诉调度程序作业什么时候触发。框架提供了一把触发器类型,但两个最常用的是SimpleTrigger和CronTrigger。SimpleTrigger为需要简单打火调度而设计。典型地,如果你需要在给定的时间和重复次数或者两次打火之间等待的秒数打火一个作业,那么SimpleTrigger适合你。另一方面,如果你有许多复杂的作业调度,那么或许需要CronTrigger。
    CronTrigger是基于Calendar-like调度的。当你需要在除星期六和星期天外的每天上午10点半执行作业时,那么应该使用CronTrigger。正如它的名字所暗示的那样,CronTrigger是基于Unix克隆表达式的。

    使用quartz说使用的maven依赖。

    

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>1.8.4</version>
</dependency>

    由于我们使用的是spring-boot框架,其目的是做到零配置文件,所以我们不使用xml文件的配置文件来定义一个定时器,而是使用向spring容器暴露bean的方式。

    向spring容器暴露所必须的bean

    

技术分享
@Configuration
public class SchedledConfiguration {

    // 配置中设定了
    // ① targetMethod: 指定需要定时执行scheduleInfoAction中的simpleJobTest()方法
    // ② concurrent:对于相同的JobDetail,当指定多个Trigger时, 很可能第一个job完成之前,
    // 第二个job就开始了。指定concurrent设为false,多个job不会并发运行,第二个job将不会在第一个job完成之前开始。
    // ③ cronExpression:0/10 * * * * ?表示每10秒执行一次,具体可参考附表。
    // ④ triggers:通过再添加其他的ref元素可在list中放置多个触发器。 scheduleInfoAction中的simpleJobTest()方法
    @Bean(name = "detailFactoryBean")
    public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduledTasks scheduledTasks){
        MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean ();
        bean.setTargetObject (scheduledTasks);
        bean.setTargetMethod ("reportCurrentByCron");
        bean.setConcurrent (false);
        return bean;
    }

    @Bean(name = "cronTriggerBean")
    public CronTriggerBean cronTriggerBean(MethodInvokingJobDetailFactoryBean detailFactoryBean){
        CronTriggerBean tigger = new CronTriggerBean ();
        tigger.setJobDetail (detailFactoryBean.getObject ());
        try {
            tigger.setCronExpression ("0/5 * * * * ? ");//每5秒执行一次
        } catch (ParseException e) {
            e.printStackTrace ();
        }
        return tigger;

    }

    @Bean
    public SchedulerFactoryBean schedulerFactory(CronTriggerBean[] cronTriggerBean){
        SchedulerFactoryBean bean = new SchedulerFactoryBean ();
        System.err.println (cronTriggerBean[0]);
        bean.setTriggers (cronTriggerBean);
        return bean;
    }
}
技术分享

    MethodInvokingJobDetailFactoryBean:此工厂主要用来制作一个jobDetail,即制作一个任务。由于我们所做的定时任务根本上讲其实就是执行一个方法。所以用这个工厂比较方便。

      注意:其setTargetObject所设置的是一个对象而不是一个类。

    CronTriggerBean:定义一个触发器。

      注意:setCronExpression:是一个表达式,如果此表达式不合规范,即会抛出异常。

    SchedulerFactoryBean:主要的管理的工厂,这是最主要的一个bean。quartz通过这个工厂来进行对各触发器的管理。

  4.对quartz的封装

    由上面代码可以看出来,此处我们设置的是一个固定的cronExpression,那么,做为项目中使用的话,我们一般是需要其动态设置比如从数据库中取出来。

    其实做法也很简单,我们只需要定义一个Trigger来继承CronTriggerBean。顶用其setCronExpression方法即可。

    那么另外一个问题,如果我们要定义两个定时任务则会比较麻烦,需要先注入一个任务工厂,在注入一个触发器。

    为了减少这样的配置,我们定义了一个抽象的超类来继承CronTriggerBean。

    具体代码如下:

    

技术分享
public abstract class BaseCronTrigger extends CronTriggerBean implements Serializable {

    private static final long serialVersionUID = 1L;

    public void init(){
        // 得到任务
        JobDetail jobdetail = new JobDetail (this.getClass ().getSimpleName (),this.getMyTargetObject ().getClass ());
        this.setJobDetail (jobdetail);
        this.setJobName (jobdetail.getName ());
        this.setName (this.getClass ().getSimpleName ());
        try {
            this.setCronExpression (this.getMyCronExpression ());
        } catch (java.text.ParseException e) {
            e.printStackTrace ();
        }

    }

    public abstract String getMyCronExpression();

    public abstract Job getMyTargetObject();

}
技术分享

    其init()方法,来为这个触发器绑定任务。其任务为一个Job类型的,也就是说其执行的任务为实现了Job接口的类,这个任务会有一个execute()方法,来执行任务题。

    

技术分享
public class ScheduledTasks implements Job {
   
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException{
        System.out.println ("Scheduling Tasks Examples By Cron: The time is now " + dateFormat ().format (new Date ()));
    }

   private SimpleDateFormat dateFormat(){
        return new SimpleDateFormat ("HH:mm:ss");
    }
}
技术分享

    为了给触发器添加任务,我们需要在子类中调用init()方法,由于spring容器注入时是使用的空参的构造函数,所以我们在此构造函数中调用init()方法。

    

技术分享
@Component
public class InitializingCronTrigger extends BaseCronTrigger implements Serializable {

    private static final long    serialVersionUID = 1L;

    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;

    public InitializingCronTrigger() {
        init ();
    }

    @Override
    public String getMyCronExpression(){
        return "0/5 * * * * ?";
    }

    @Override
    public Job getMyTargetObject(){
        return new ScheduledTasks ();
    }

    public void parse(){
        try {
            schedulerFactoryBean.getObject ().pauseAll ();
        } catch (SchedulerException e) {
            e.printStackTrace ();
        }
    }

}
技术分享

    此时我们只需要在配置类中加入一个配置就可以了。

    

技术分享
  @Bean
    public SchedulerFactoryBean schedulerFactory(CronTriggerBean[] cronTriggerBean){
        SchedulerFactoryBean bean = new SchedulerFactoryBean ();
        System.err.println (cronTriggerBean[0]);
        bean.setTriggers (cronTriggerBean);

        return bean;
    }
技术分享

 

  4.介绍一个cronExpression表达式。

    这一部分是摘抄的:

      

字段 允许值 允许的特殊字符
  0-59   , - * /
  0-59   , - * /
小时   0-23   , - * /
日期   1-31   , - * / L W C
月份   1-12 或者 JAN-DEC   , - * /
星期   1-7 或者 SUN-SAT   , - * / L C #
年(可选)   留空, 1970-2099   , - * /

 
如上面的表达式所示:

“*”字符被用来指定所有的值。如:”*“在分钟的字段域里表示“每分钟”。

“-”字符被用来指定一个范围。如:“10-12”在小时域意味着“10点、11点、12点”。

“,”字符被用来指定另外的值。如:“MON,WED,FRI”在星期域里表示”星期一、星期三、星期五”.

“?”字符只在日期域和星期域中使用。它被用来指定“非明确的值”。当你需要通过在这两个域中的一个来指定一些东西的时候,它是有用的。看下面的例子你就会明白。


“L”字符指定在月或者星期中的某天(最后一天)。即“Last ”的缩写。但是在星期和月中“L”表示不同的意思,如:在月子段中“L”指月份的最后一天-1月31日,2月28日,如果在星期字段中则简单的表示为“7”或者“SAT”。如果在星期字段中在某个value值得后面,则表示“某月的最后一个星期value”,如“6L”表示某月的最后一个星期五。

“W”字符只能用在月份字段中,该字段指定了离指定日期最近的那个星期日。

“#”字符只能用在星期字段,该字段指定了第几个星期value在某月中


每一个元素都可以显式地规定一个值(如6),一个区间(如9-12),一个列表(如9,11,13)或一个通配符(如*)。“月份中的日期”和“星期中的日期”这两个元素是互斥的,因此应该通过设置一个问号(?)来表明你不想设置的那个字段。表7.1中显示了一些cron表达式的例子和它们的意义:

表达式

 意义
"0 0 12 * * ?"   每天中午12点触发
"0 15 10 ? * *"   每天上午10:15触发
"0 15 10 * * ?"   每天上午10:15触发
"0 15 10 * * ? *"   每天上午10:15触发
"0 15 10 * * ? 2005"   2005年的每天上午10:15触发
"0 * 14 * * ?"   在每天下午2点到下午2:59期间的每1分钟触发
"0 0/5 14 * * ?"   在每天下午2点到下午2:55期间的每5分钟触发
"0 0/5 14,18 * * ?"   在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
"0 0-5 14 * * ?"   在每天下午2点到下午2:05期间的每1分钟触发
"0 10,44 14 ? 3 WED"   每年三月的星期三的下午2:10和2:44触发
"0 15 10 ? * MON-FRI"   周一至周五的上午10:15触发
"0 15 10 15 * ?"   每月15日上午10:15触发
"0 15 10 L * ?"   每月最后一日的上午10:15触发
"0 15 10 ? * 6L"   每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6L 2002-2005"   2002年至2005年的每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6#3"   每月的第三个星期五上午10:15触发

           每天早上6点 0 6 * * *

            每两个小时 0 */2 * * *

            晚上11点到早上8点之间每两个小时,早上八点 0 23-7/2,8 * * *

每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点 0 11 4 * 1-3

            1月1日早上4点 0 4 1 1 *

 

http://www.cnblogs.com/lic309/p/4089633.html

 

spring-boot-quartz, 依赖spring-boot-parent

标签:方便   code   hub   tailf   rem   对象   arraylist   copy   属性   

原文地址:http://www.cnblogs.com/softidea/p/5995070.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!