定时任务基类
package com.bessky.common.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.thread.ThreadUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.bessky.common.core.function.TeConsumer; import com.bessky.common.core.util.ContextUtils; import com.bessky.common.core.util.ThreadUtils; import com.xxl.job.core.context.XxlJobHelper; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.core.StringRedisTemplate; import javax.annotation.Resource; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; public abstract class BaseJobHandler { /** * 日志记录器 */ protected final Logger log = LoggerFactory.getLogger(this.getClass()); @Resource protected StringRedisTemplate stringRedisTemplate; /** * 循环执行任务 * * @param items * @param action * @param error * @param size * @param <T> */ protected <T> void execute(Collection<T> items, Consumer<T> action, BiConsumer<T, Exception> error, int size) { if (CollUtil.isEmpty(items)) { return; } // 创建执行线程 ExecutorService executor = ThreadUtil.newExecutor(size, size, items.size()); // 循环执行任务 items.forEach(item -> executor.execute(() -> { try { action.accept(item); } catch (Exception e) { log.error(e.getMessage(), e); if (error != null) { error.accept(item, e); } else { XxlJobHelper.log(e); } } })); // 等待执行完成 ThreadUtils.await(executor); } /** * 循环执行任务 * * @param items * @param action * @param error * @param <T> */ protected <T> void execute(Collection<T> items, Consumer<T> action, BiConsumer<T, Exception> error) { this.execute(items, action, error, 100); } /** * 循环执行任务 * * @param map * @param action * @param error * @param size * @param <K> * @param <V> */ protected <K, V> void execute(Map<K, V> map, BiConsumer<K, V> action, TeConsumer<K, V, Exception> error, int size) { if (MapUtil.isEmpty(map) || action == null) { return; } // 创建执行线程 ExecutorService executor = ThreadUtil.newExecutor(size, size, map.size()); // 循环执行任务 map.forEach((key, value) -> executor.execute(() -> { try { action.accept(key, value); } catch (Exception e) { log.error(e.getMessage(), e); if (error != null) { error.accept(key, value, e); } else { XxlJobHelper.log(e); } } })); // 等待执行完成 ThreadUtils.await(executor); } /** * 循环执行任务 * * @param map * @param action * @param error * @param <K> * @param <V> */ protected <K, V> void execute(Map<K, V> map, BiConsumer<K, V> action, TeConsumer<K, V, Exception> error) { this.execute(map, action, error, 100); } /** * 获取用户标识 * * @return */ protected String getUserId() { Integer userId = ContextUtils.getUserId(); return userId != null ? userId.toString() : "0"; } /** * 记录调试日志 * * @param format * @param arguments */ protected void debug(String format, Object... arguments) { log.debug(format, arguments); XxlJobHelper.log(format, arguments); } /** * 记录警告日志 * * @param format * @param arguments */ protected void warn(String format, Object... arguments) { log.warn(format, arguments); XxlJobHelper.log(format, arguments); } /** * 记录错误日志 * * @param format * @param arguments */ protected void error(String format, Object... arguments) { log.error(format, arguments); XxlJobHelper.log(format, arguments); } /** * 记录错误日志 * * @param msg * @param t */ protected void error(String msg, Throwable t) { log.error(msg, t); XxlJobHelper.log(t); } /** * 指定操作限流 * * @param key * @param timeout * @param unit * @return */ protected Boolean limit(String key, long timeout, TimeUnit unit) { String userId = ContextUtils.getUserId(0).toString(); return stringRedisTemplate.opsForValue().setIfAbsent(key, userId, timeout, unit); } /** * 限流两个小时 * * @param key * @return */ protected Boolean limit2hour(String key) { return this.limit(key, 2, TimeUnit.HOURS); } /** * 解析字符参数 * * @param key * @return */ protected String parseStringParam(String key) { // 获取作业参数 String jobParam = XxlJobHelper.getJobParam(); if (!JSON.isValidObject(jobParam)) { return null; } // 解析作业参数 return JSON.parseObject(jobParam).getString(key); } /** * 解析字符参数 * * @param key * @param other * @return */ protected String parseStringParam(String key, String other) { return Optional.ofNullable(key).map(this::parseStringParam).filter(StringUtils::isNotBlank).orElse(other); } /** * 解析字符参数 * * @param key * @param other * @return */ protected String parseStringParam(String key, Supplier<String> other) { return Optional.ofNullable(key).map(this::parseStringParam).filter(StringUtils::isNotBlank).orElseGet(other); } /** * 解析对象参数 * * @param key * @param clazz * @param <T> * @return */ protected <T> T parseObjectParam(String key, Class<T> clazz) { // 获取作业参数 String jobParam = XxlJobHelper.getJobParam(); if (!JSON.isValidObject(jobParam)) { return null; } // 解析作业参数 return JSON.parseObject(jobParam).getObject(key, clazz); } /** * 解析对象参数 * * @param key * @param clazz * @param other * @param <T> * @return */ protected <T> T parseObjectParam(String key, Class<T> clazz, T other) { T value = this.parseObjectParam(key, clazz); return Optional.ofNullable(value).orElse(other); } /** * 解析对象参数 * * @param key * @param other * @param clazz * @param <T> * @return */ protected <T> T parseObjectParam(String key, Supplier<T> other, Class<T> clazz) { T value = this.parseObjectParam(key, clazz); return Optional.ofNullable(value).orElseGet(other); } /** * 解析列表参数 * * @param key * @param clazz * @param <T> * @return */ protected <T> List<T> parseListParam(String key, Class<T> clazz) { // 获取作业参数 String jobParam = XxlJobHelper.getJobParam(); if (!JSON.isValidObject(jobParam)) { return null; } // 解析作业参数 JSONArray jsonArray = JSON.parseObject(jobParam).getJSONArray(key); if (CollectionUtils.isEmpty(jsonArray)) { return null; } // 转换参数列表 return jsonArray.toJavaList(clazz); } /** * 解析映射参数 * * @param key * @return */ protected Map<String, String> parseMapParam(String key) { // 获取作业参数 String jobParam = XxlJobHelper.getJobParam(); if (!JSON.isValidObject(jobParam)) { return null; } // 解析作业参数 return JSON.parseObject(jobParam).getObject(key, new TypeReference<Map<String, String>>() { }); } /** * 解析作业参数 * * @param key * @return */ protected JSONObject parseJsonObject(String key) { // 获取作业参数 String jobParam = XxlJobHelper.getJobParam(); if (!JSON.isValidObject(jobParam)) { return null; } // 解析作业参数 return JSON.parseObject(jobParam).getJSONObject(key); } }