springboot中使用定时任务,异步调用,自定义配置参数(八)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014401141/article/details/78638957

1.定时任务


1.1定时任务的几种实现方式;

Timer:Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。
Quartz:使用Quartz,这是一个功能比较强大的的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行,配置起来稍显复杂。
Spring Task:Spring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多。

1.2使用spring task实现定时任务

在Spring Boot的主类中加入@EnableScheduling注解,启用定时任务的配置

@EnableScheduling//开启定时任务注解
编写定时任务

package com.ljl.spring.boot;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ScheduledTasks {

//固定等待时间 @Scheduled(fixedDelay = 时间间隔 )

   //  固定间隔时间 @Scheduled(fixedRate = 时间间隔 )

//Corn表达式 @Scheduled(cron = Corn表达式)

  @Scheduled(cron = "0/10 * * * * *") 用表达式  public void add() { System. out.println( "我正在执行.."+System. currentTimeMillis()); }}

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

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

启动就好了


2.1使用Spring quartz实现定时任务

2.1.1pom.xml添加依赖

<!--定时任务quartz-->
<dependency>
   <groupId>org.quartz-scheduler</groupId>
   <artifactId>quartz</artifactId>
   <version>2.2.1</version>
</dependency>

<!--Spring 项目整合 Quartz 主要依靠添加 SchedulerFactoryBean 这个 FactoryBean ,
所以在maven 依赖中添加 spring-context-support 。-->
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context-support</artifactId>
</dependency>

2.1.2任务类

package com.ljl.spring.boot.job;

import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;

@Component
@Configurable
@EnableScheduling
public class QuartzScheduledTasks {

   public void test() {
      System.out.println("我正在执行.."+System.currentTimeMillis());
   }

}


2.1.3Quartz配置类

package com.ljl.spring.boot.config;

import com.ljl.spring.boot.job.QuartzScheduledTasks;
import org.quartz.Trigger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
/**
 * quartz配置
 **/
@Configuration
public class SchedledConfiguration {
    /**
     * Details:配置定时任务
     */
    @Bean(name = "jobDetail")
    public MethodInvokingJobDetailFactoryBean detailFactoryBean(QuartzScheduledTasks quartzScheduledTasks) { // quartzScheduledTasks为需要执行的任务
        MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
//           是否并发执行
//           例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了,
//          如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行
        jobDetail.setConcurrent(false);
        jobDetail.setName("srd-chhliu");// 设置任务的名字
        jobDetail.setGroup("srd");// 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使用
        // 为需要执行的实体类对应的对象
        jobDetail.setTargetObject(quartzScheduledTasks);
        //test为需要执行的方法
        //通过这几个配置,告诉JobDetailFactoryBean我们需要执行定时执行ScheduleTask类中的sayHello方法
        jobDetail.setTargetMethod("test");
        return jobDetail;
    }

    /**
     * Details:配置定时任务的触发器,也就是什么时候触发执行定时任务
     */
    @Bean(name = "jobTrigger")
    public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) {
        CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
        tigger.setJobDetail(jobDetail.getObject());
        // 每天下午的 11点到11点59分(整点开始,每隔5分触发)
        tigger.setCronExpression("0 0/1 11 * * ?");// 初始时的cron表达式
        tigger.setName("srd-chhliu");// trigger的name
        return tigger;
    }

    /**
     * Details:定义quartz调度工厂
     */
    @Bean(name = "scheduler")
    public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        // 用于quartz集群,QuartzScheduler 启动时更新己存在的Job
        bean.setOverwriteExistingJobs(true);
        // 延时启动,应用启动1秒后
        bean.setStartupDelay(1);
        // 注册触发器
        bean.setTriggers(cronJobTrigger);
        return bean;
    }

}


在Spring Boot的主类中加入@EnableScheduling注解,启用定时任务的配置

@EnableScheduling//开启定时任务注解 


2.1.4 、定时查库,并更新任务

import com.ljl.spring.boot.mapper.ConfigMappper;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;

/**
 * 从数据库定时更新任务
 **/
@Configuration
@EnableScheduling
@Component
public class ScheduleRefreshDatabase {
    @Autowired
    private ConfigMappper configMappper;
    @Resource(name = "jobDetail")
    private JobDetail jobDetail;
    @Resource(name = "jobTrigger")
    private CronTrigger cronTrigger;
    @Resource(name = "scheduler")
    private Scheduler scheduler;

    @Scheduled(fixedRate = 5000) // 每隔5s查库,并根据查询结果决定是否重新设置定时任务
    public void scheduleUpdateCronTrigger() throws SchedulerException {
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
        String currentCron = trigger.getCronExpression();// 当前Trigger使用的
        String searchCron = configMappper.getConfig().get(0).getCron();// 从数据库查询出来的
        System.out.println(currentCron);
        System.out.println(searchCron);
        if (currentCron.equals(searchCron)) {
            // 如果当前使用的cron表达式和从数据库中查询出来的cron表达式一致,则不刷新任务
        } else {
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(searchCron);
            // 按新的cronExpression表达式重新构建trigger
            trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
            trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey())
                    .withSchedule(scheduleBuilder).build();
            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(cronTrigger.getKey(), trigger);
            currentCron = searchCron;
        }
    }
}

相关sql

CREATE TABLE `config` (
  `id` int(20) NOT NULL AUTO_INCREMENT,
  `cron` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


参考: http://blog.csdn.net/growing_duck/article/details/75115913

http://blog.csdn.net/liuchuanhong1/article/details/60873295

3、使用@Async实现异步调用

启动加上@EnableAsync ,需要执行异步方法上加入  @Async

例如

@Async
public void sedSms() {
    System.out.println("##sedSms##开始执行..  2");
    for (int i = 0; i < 5; i++) {
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            // TODO: handle exception
        }
        System.out.println("i:" + i);
    }
    System.out.println("##sedSms##结束执行..  3");
}

4、自定义参数

application.properties配置文件中添加

#自定义参数
name=hello

配置文件值

      @Value("${name}")

      private Stringname;

@ResponseBody

      @RequestMapping("/getValue")

      public String getValue() {

            returnname;

      }


5、修改端口号

#修改端口
server.port=8081
#修改应用路径
server.context-path=/spring-boot



猜你喜欢

转载自blog.csdn.net/u014401141/article/details/78638957