1. 需求描述
现在需要做一个定时发布消息的功能,到了设置的发布时间就把消息发给指定人群.
2. 思路
- 把设置的发布时间转换成java定时任务时间表达式
- 把消息对象和时间表达式添加至任务调度
- 在任务调度中完成具体业务实现
3. 代码实现
3.1 添加消息至任务调度
@Resource
private ScheduledTaskManager scheduledTaskManager;
public Response<ResponseEnum> addMessage(MessageVo vo) {
scheduledTaskManager.addScheduled(vo, CronUtil.date2cron(parse));
}
3.2 任务调度
import com.config.pool.ScheduledProcessPool;
import com..mapper.UserMapper;
import com..mapper.message.MessageMapper;
import com..vo.message.MessageVo;
import com.vo.sys.SubAccountVo;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.stream.Collectors;
/**
* @Description: 定时发布消息任务调度
*/
@Component
public class ScheduledTaskManager {
@Resource
private MessageMapper messageMapper;
@Resource
private UserMapper userMapper;
private static Map<Integer, ScheduledFuture<?>> scheduleFutureMap = ScheduledProcessPool.INSTANCE.getPool();
private ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
private ScheduledFuture<?> schedule;
/*
* 描述:新增任务调度
* @param vo 定时任务消息对象
* @param cron 时间表达式
*/
public void addScheduled(MessageVo vo, String cron) {
//移除key的任务调度
removeScheduled(vo.getId());
threadPoolTaskScheduler.initialize();
//新增任务调度
schedule = threadPoolTaskScheduler.schedule(() -> {
//此处进行定时调度的业务操作
// 默认给所有用户发消息
List<SubAccountVo> list = userMapper.getAllAccount();
List<Integer> userIdList = list.stream().map(SubAccountVo::getId).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(vo.getUserIdList())){
//如果消息接收者不为空 则给指定用户发消息
userIdList = vo.getUserIdList();
}
messageMapper.insertMessUserLink(vo.getId(),userIdList);
}, new CronTrigger(cron));
if (schedule != null) {
scheduleFutureMap.put(vo.getId(), schedule);
}
}
/**
* 描述:移除任务调度
*
* @param key 定时任务key
*/
public void removeScheduled(Integer key) {
//先取消任务调度
ScheduledFuture<?> future = scheduleFutureMap.get(key);
if (future != null && !future.isDone()) {
future.cancel(true);
}
//并将任务调度从map中移除
if (scheduleFutureMap.containsKey(key)) {
Iterator<Integer> it = scheduleFutureMap.keySet().iterator();
while (it.hasNext()) {
if (it.next().equals(key)) {
it.remove();
break;
}
}
}
}
}
3.3 时间转换类
把设置的发布时间转换成java定时任务时间表达式
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Description:时间转换成Cron表达式
*/
public class CronUtil {
//cron表达式格式
private static final String cron = "ss mm HH dd MM ?";
/**
* 时间转换成Cron表达式
* "1/5 * * * * ?";
*/
public static String date2cron(Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(cron);
return simpleDateFormat.format(date);
}
}