一、简介及配置
- 项目环境
使用dubbo分布式结构,创建一个定时任务的子工程 - 配置文件
spring-redis.xml文件
redis没有密码的配置,如果有密码,在最后的bean中加入<constructor-arg name="password" value="12345"/>
spring-jobs.xml 定时任务配置<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!--jedis 连接池的相关配置--> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal"> <value>200</value> </property> <property name="maxIdle"> <value>50</value> </property> <property name="testOnBorrow" value="true"/> <property name="testOnReturn" value="true"/> </bean> <bean id="jedisPool" class="redis.clients.jedis.JedisPool"> <constructor-arg name="poolConfig" ref="jedisPoolConfig"/> <constructor-arg name="host" value="127.0.0.1"/> <constructor-arg name="port" value="6379" type="int"/> <constructor-arg name="timeout" value="30000" type="int"/> </bean> </beans>
里面的配置需要自定义一个类和方法,详请见下
pom.xml依赖<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!--开启spring注解使用--> <context:annotation-config></context:annotation-config> <!--注册自定义job--> <bean id="clearImgQuartz" class="com.sys.jobs.ClearImgQuartz"/> <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <!--注入对象--> <property name="targetObject" ref="clearImgQuartz"/> <!--注入方法--> <property name="targetMethod" value="clearImg"/> </bean> <!--触发器 指定时间--> <bean id="triggerFactoryBean" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <!--注入jobDetail--> <property name="jobDetail" ref="jobDetail"/> <!--触发时间,基于cron表达式 ,每周一上午10点15分执行任务--> <property name="cronExpression" value="0 15 10 ? * MON"/> </bean> <!--调度工厂--> <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <!--注入触发器--> <property name="triggers"> <list> <ref bean="triggerFactoryBean"/> </list> </property> </bean> </beans>
web.xml配置<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> </dependency>
读取spring资源文件<!-- 加载spring容器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
二、定时任务类
-
ClearImgQuartz 类
/** * 定时清理七牛云垃圾图片 */ @Slf4j public class ClearImgQuartz { //根据redis清除七牛图片 @Autowired private JedisPool jedisPool; /** * 删除垃圾图片 */ public void clearImg(){ //根据redis中保存的两个set集合进行差值计算 //得到垃圾图片的集合,然后删除 Set<String> set = jedisPool.getResource(). sdiff(RedisConstant.SETMEAL_PIC_RESOURCES, RedisConstant.SETMEAL_PIC_DB_RESOURCES); log.info("垃圾图片集合:"+set); if(set != null){ for (String picName : set){ //根据图片名字删除 QiNiuYun.deleteImg(picName); //删除redis集合中的图片名称 jedisPool.getResource().srem(RedisConstant.SETMEAL_PIC_RESOURCES,picName); log.info("图片删除成功,删除的图片名称是:"+picName); } } } }
-
QiNiuYun工具类
对图片文件进行上传及删除/** * 七牛云-图片上传工具类 * @author hp */ public class QiNiuYun { //1.定义静态参数 public static String accessKey = "你的AK码"; public static String secretKey = "你的SK码"; public static String bucket = "空间名称"; /* //文件上传----测试 public static void uploadToQiNiuYun(String filePath, String fileName) { //构造一个带指定 Region 对象的配置类 Configuration cfg = new Configuration(Zone.autoZone()); UploadManager uploadManager = new UploadManager(cfg); Auth auth = Auth.create(accessKey, secretKey); String upToken = auth.uploadToken(bucket); try { Response response = uploadManager.put(filePath, fileName, upToken); //解析上传成功的结果 DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); System.out.println(putRet.key); System.out.println(putRet.hash); } catch (QiniuException ex) { Response r = ex.response; System.err.println(r.toString()); try { System.err.println(r.bodyString()); } catch (QiniuException ex2) { //ignore } } }*/ //字节数组上传 public static void uploadToQiNiuYun(byte[] bytes, String fileName) { //构造一个带指定 Region 对象的配置类 Configuration cfg = new Configuration(Zone.autoZone()); UploadManager uploadManager = new UploadManager(cfg); Auth auth = Auth.create(accessKey, secretKey); String upToken = auth.uploadToken(bucket); String key = fileName; try { Response response = uploadManager.put(bytes, key, upToken); //解析上传成功的结果 DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); System.out.println(putRet.key); System.out.println(putRet.hash); } catch (QiniuException ex) { Response r = ex.response; System.err.println(r.toString()); try { System.err.println(r.bodyString()); } catch (QiniuException ex2) { //ignore } } } /** * 删除图片 * @param fileName */ public static void deleteImg(String fileName){ Configuration cfg = new Configuration(Zone.zone2()); Auth auth = Auth.create(accessKey, secretKey); String key = fileName; BucketManager bucketManager = new BucketManager(auth, cfg); try { bucketManager.delete(bucket, key); } catch (QiniuException ex) { //如果遇到异常,说明删除失败 System.err.println(ex.code()); System.err.println(ex.response.toString()); } } }
-
RedisConstant类
存放redis常量参数/** * redis数据库常量参数 * @author hp */ public class RedisConstant { //套餐的所有图片名称 public static final String SETMEAL_PIC_RESOURCES = "setmealPicResources"; //套餐图片保存到数据库的所有图片名称 public static final String SETMEAL_PIC_DB_RESOURCES = "setmealPicDbResources"; }
三、向redis数据库添加两个set集合
- 在图片上传时,向数据库添加数据
@Autowired private JedisPool jedisPool; /** * 图片文件上传 * @param imgFile * @return */ @RequestMapping("/upload") public Result upload(@RequestParam("imgFile")MultipartFile imgFile){ log.info("imgFile:"+ imgFile); //原始文件名 String fileName = imgFile.getOriginalFilename(); //找到xxx.jpg的点 int index = fileName.lastIndexOf("."); //获取.jpg String extention = fileName.substring(index - 1); //使用UUID修改原始名字 String newFileName = UUID.randomUUID().toString() + extention; log.info("修改后的文件名称:" + newFileName); //图片上传到七牛云 try { QiNiuYun.uploadToQiNiuYun(imgFile.getBytes(),newFileName); log.info("上传成功,图片放入redis中------"); //TODO 在图片上传时,把图片名称放入redis数据库中存储 jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_RESOURCES,newFileName); } catch (IOException e) { e.printStackTrace(); return new Result(false,"图片上传失败!"); } return new Result(true,"图片上传成功!",newFileName); }
- 在添加数据时,向数据库添加数据
@Autowired private JedisPool jedisPool; /** * 添加setmeal对象和中间表数据 * @param setmeal * @param itemgroupIds */ @Override public void add(Setmeal setmeal, Integer[] itemgroupIds) { setmealDao.insert(setmeal); Integer setmealId = setmeal.getId(); setMealAndItemGroup(setmealId,itemgroupIds); //TODO 在执行添加操作时,把图片名称存入redis数据库中 jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES,setmeal.getImg()); }