初窥门径定时任务:QuartzJobBean

定时任务:QuartzJobBean

以我做天气预报项目为例概述定时任务的使用:

第一步:写一个要定时执行的任务的类,让他继承QuartzJobBean (类上不加@component)

package com.sinux.weather.controller;

import com.sinux.weather.entity.City;
import com.sinux.weather.service.RemoteCities;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author liaoc
 */
@Slf4j
public class WeatherSave extends QuartzJobBean {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RemoteCities remoteCities;
	/**
	*StringRedisTemplate继承RedisTemplate
	*StringRedisTemplate默认采用的是String的序列化策略,
	*保存的key和value都是采用此策略序列化保存的。
	*当Redis当中的数据值是以可读的形式显示出来的时候,
	*只能使用StringRedisTemplate才能		   获取到里面的数据
	*RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的
	*当你的redis数据库里面本来存的是字符串数据或者你要存取的数据就
	*是字符串类型数据的时候,
	*那么你就使用StringRedisTemplate即可,但是如果你的数据是复杂的对象类型,
	*而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,
	*那么使用RedisTemplate是更好的选择
	**/
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private final Long TIME_OUT = 60L;

    private String WEATHER_API="http://wthrcdn.etouch.cn/weather_mini";

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
       log.info("调度任务开始===================================");
        List<City> cityList = null;
        try {
            cityList = remoteCities.getCityLists();
        } catch (Exception e) {
            log.error("获取城市列表异常…………………………");
            e.printStackTrace();
        }
        String cityId = null;
        for(int i=0;i<cityList.size();i++){
            cityId = cityList.get(i).getCityId();
            getWeatherInfo(cityId);
        }

    }

    private void getWeatherInfo(String cityId) {
        log.info("Start 同步天气cityId:"+cityId);
        ValueOperations<String,String> ops =
                stringRedisTemplate.opsForValue();

        String uri = WEATHER_API+"?citykey="+cityId;
        String key = uri;
        ResponseEntity<String> response = null;
        try {
            response = restTemplate.getForEntity(uri,String.class);
        } catch (RestClientException e) {
            log.error("查询失败============");
            e.printStackTrace();
        }
        String strBody = null;
        if (response.getStatusCode().value() == 200) {
            strBody = response.getBody();
        }
        log.info("往redis里存放数据==================");
        ops.set(key,strBody,TIME_OUT, TimeUnit.SECONDS);
    }
}

二 写一个配置类SaveWeatherUtil,用于设置定时时间。间隔等

package com.sinux.weather.util;

import com.sinux.weather.controller.WeatherSave;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author liaoc
 */
@Configuration
public class SaveWeatherUtil{
    private final int TIME =  60;
    @Bean
    public JobDetail weatherDataSycJobDetail(){
        //创建一个JobDetail实例
        JobDetail jobDetail =
                JobBuilder.//JobBuilder,用于声明一个任务实例,也可以定义关于该任务的详情比如任务名、组名等
                        newJob(WeatherSave.class).// 任务执行类(对应上面的任务类)
                        withIdentity("weatherSave","group1").//job 的name和group.任务名,任务组,如果没有调用 withIdentity(..) 指定 job 的名字,会自动生成一个
                        storeDurably().
                        build();
        return  jobDetail;
    }

    /**
     * 触发器
     * @return
     */
    @Bean
    public Trigger sampleJobTrigger(){
        //设置触发时间
        SimpleScheduleBuilder simpleScheduleBuilder =
                SimpleScheduleBuilder.
                simpleSchedule().
                        withIntervalInSeconds(TIME).//设置间隔执行时间
                        repeatForever();//设置执行次数,也可设置执行次数.withRepeatCount(10)

        //Trigger,触发器,表明任务在什么时候会执行
        Trigger trigger =
                TriggerBuilder.//TriggerBuilder,触发器创建器,用于创建触发器 trigger
                        newTrigger().
                        forJob(weatherDataSycJobDetail()).
                        withIdentity("weatherDataSyncTrigger").//如果没有使用 withIdentity(..) 会自动生成一个触发器名称
                        withSchedule(simpleScheduleBuilder).//用于创建 Trigger,如果没有调用 withSchedule(..) 方法,会使用默认的 schedule
                        build();
        //.endAt(dateOf(22, 0, 0)) 直到22:00终结触发器

        return trigger;
    }
}

这样就可以定时的获取天气信息并存入redis

发布了67 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/m0_37635053/article/details/104776953