1 定时任务组件Quartz
1.1 Quartz介绍1.2 Quartz框架的使用思路1.3.Quartz框架的基本使用方式1.3 Corn表达式1.4 cron表达式在线生成器1.5.spring整合 Quartz定时框架1.6.创建 Job类1.7.Spring整合Quartz1.8.编写测试代码 二、redis补充知识
1.9 定时清理垃圾图片
1 定时任务组件Quartz 1.1 Quartz介绍
官网:http://www.quartz-scheduler.org/
1)job - 任务 - 你要做什么事?
2)Trigger - 触发器 - 你什么时候去做?
3)Scheduler - 任务调度 - 你什么时候需要去做什么事?
添加Quartz依赖:
org.quartz-scheduler quartz
(1) 自定义一个Job
public class QuartzDemo implements Job {
//任务
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("现在时刻:"+new Date());
}
}
(2) 编写main方法进行测试
public class QuartzTest {
public static void main(String[] args) throws SchedulerException {
//1、创建job:做什么事
JobDetail job = JobBuilder.newJob(QuartzDemo.class).build();
//2、创建trigger:什么时候
CronTrigger trigger = TriggerBuilder.newTrigger().withSchedule(
CronScheduleBuilder.cronSchedule("0/1 * * * * ?")
).build();
//3、创建scheduler:什么时候做什么事
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.scheduleJob(job,trigger);
scheduler.start();
}
}
查看控制台:
执行上面main方法观察控制台,可以发现每隔1秒会输出一次,说明每隔1秒自定义 Job被调用一次。
Cron 表达式是一个字符串,分为 6 或 7 个域,每一个域代表一个含义
Cron 有如下两种语法格式:
(1)Seconds Minutes Hours Day Month Week Year
(2)Seconds Minutes Hours Day Month Week
一、结构
corn 从左到右(用空格隔开):秒 分 小时 月份中的日期 月份 星期中的日期 年份
二、cron表达式
字段含义:
示例:
“?”字符只在日期域和星期域中使用。它被用来指定“非明确的值”。
例如:
想在每月的20日触发调度0 0 0 20 * ?,而且只能使用如下写法:0/1 0 0 20 * ?。其中最后一位只能用?,而不能使 用*,因为*表示不管星期几都会触发恰好与20冲突。
前面介绍了cron表达式,但是自己编写表达式还是有一些困难的,我们可以借助一些 cron表达式在线生成器来根据我们的需求生成表达式即可。
http://cron.qqe2.com/
public class QuartzDemo2 {
public void execute(){
System.out.println("现在时刻:"+new Date());
}
}
1.7.Spring整合Quartz
1.8.编写测试代码
public class QuartzTest {
public static void main(String[] args) throws SchedulerException, IOException {
new ClassPathXmlApplicationContext("applicationContext-quartz.xml");
}
}
控制台定时输出。
二、redis补充知识---------------------------redis----------------------- 一、哪儿用了redis?为什么要用redis? 哪儿用了:App启动后的轮播广告 为什么用:因为mysql是硬盘,顶不住搞并发;redis是内存; 二、什么是redis? redis是c语言开发的高性能的k-v形式的数据库,数据存储在内存中 三、reids基本命令 incr和decr:自增和自减 exists:判断key值是否存在 keys *:查看所有key expire和ttl:设置和查看失效时间 四、redis的多数据库实例 1、redis实例中提供了下标是0-15的16个数据库,可以通过select切换 2、清空数据库的命令: flushdb:清空当前数据库的数据 flushall:清空所有数据库的数据 五、redis的三种数据类型 赋值 取值 删除 特点 string set k get k del k string hash hset k k v hget k k hdel k k map set sadd k v... smembers k srem k v 无序,不可重复1.9 定时清理垃圾图片
前面我们已经完成了体检套餐的管理,在新增套餐时套餐的基本信息和图片是分两次提 交到后台进行操作的。也就是用户首先将图片上传到七牛云服务器,然后再提交新增窗 口中录入的其他信息。如果用户只是上传了图片而没有提交录入的其他信息,此时的图 片就变为了垃圾图片,因为在数据库中并没有记录它的存在。此时我们要如何处理这些 垃圾图片呢?
解决方案就是通过定时任务组件定时清理这些垃圾图片。为了能够区分出来哪些图片是 垃圾图片,我们在文件上传成功后将图片保存到了一个redis集合中,当套餐数据插入到 数据库后我们又将图片名称保存到了另一个redis集合中,通过计算这两个集合的差值就 可以获得所有垃圾图片的名称。
本章节我们就会基于Quartz定时任务,通过计算redis两个集合的差值找出所有的垃圾图 片,就可以将垃圾图片清理掉。
操作步骤:
(1) 创建maven工程health_jobs,打包方式为war导入Quartz等相关坐标。
health_parent com.qf 1.0-SNAPSHOT 4.0.0 health_jobs war com.qf health_interface 1.0-SNAPSHOT org.quartz-scheduler quartz org.apache.tomcat.maven tomcat7-maven-plugin 83 /
(2) 配置web.xml
Archetype Created Web Application contextConfigLocation classpath:applicationContext-*.xml org.springframework.web.context.ContextLoaderListener
(3) 配置log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file mylog.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=c:\mylog.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=debug, stdout
(4) 配置applicationContext-job.xml
ClearImgJob.java
package com.xii.job;
import com.xii.constant.RedisConstant;
import com.xii.utils.QiniuUtils;
import redis.clients.jedis.JedisPool;
import java.util.Date;
import java.util.Set;
public class ClearImgJob {
//注入jedis 直接使用getset 省的扫描注解
private JedisPool jedisPool;
//set 将bean注入
public void setJedisPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
public void clearImg(){
Set rubbishimg = jedisPool.getResource().sdiff(RedisConstant.SETMEALIMG_REDIS, RedisConstant.SETMEALIMG_DB_REDIS);
for (String img : rubbishimg) {
QiniuUtils.deleteFileFromQiniu(img);
jedisPool.getResource().srem(RedisConstant.SETMEALIMG_REDIS,img);
System.out.println(new Date()+" remove img name : "+img);
}
}
}
在health_backed中:
在controller中
//注入redis
@Autowired
private JedisPool jedisPool;
@PostMapping("/add")
@ResponseBody
public Result add(Integer[] checkgroupIds,@RequestBody Setmeal setmeal){
try {
setmealService.add(checkgroupIds,setmeal);
//在redis中添加已经上传的图片
jedisPool.getResource().sadd(RedisConstant.SETMEALIMG_DB_REDIS,setmeal.getImg());
return new Result(true, MessageConstant.ADD_SETMEAL_SUCCESS);
} catch (Exception e) {
e.printStackTrace();
return new Result(true,MessageConstant.ADD_SETMEAL_FAIL);
}
}
@RequestMapping("/upload")
@ResponseBody
public Result upload(MultipartFile imgFile){
try {
//1、重命名
String originalFilename = imgFile.getOriginalFilename();
String extName = originalFilename.substring(originalFilename.lastIndexOf("."));
String fileName = UUID.randomUUID().toString()+extName;
//2、上传到七牛云
QiniuUtils.upload2Qiniu(imgFile.getBytes(),fileName);
//3、存储到redis 用于GC
jedisPool.getResource().sadd(RedisConstant.SETMEALIMG_REDIS,fileName);
return new Result(true, MessageConstant.PIC_UPLOAD_SUCCESS,fileName);
}catch (Exception e){
e.printStackTrace();
return new Result(false, MessageConstant.PIC_UPLOAD_FAIL);
}
}
applicationContext-redis.xml
springmvc.xml引入applicationContext-redis.xml
引入定时组件后:
如果用户上传文件而没有保存,就会删除这张图片



