Tarea programada: QuartzJobBean
Tómeme como un proyecto de pronóstico del tiempo como un ejemplo para describir el uso de tareas programadas:
El primer paso: escribir una clase de tareas que se ejecutarán regularmente, dejar que herede QuartzJobBean (@component no se agrega a la clase)
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);
}
}
Dos escriben una clase de configuración SaveWeatherUtil, utilizada para establecer el tiempo de temporización. Intervalo etc.
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;
}
}
De esta manera, puede obtener regularmente información sobre el clima y almacenarla en redis