写了一个项目需要在一定时间触发发送消息的接口
需求是:
①在会议开始前10分钟发送会议邀请
②在会议开始时发送参会通知
③在会议结束时发送会议结束通知
我的思路如下:
在新增会议的时候获取参会时间,到达各个时间点自动调用发送消息的接口就可以了
cooperative是我会议的实体类
由于考虑到会议时间是可以修改的,但是我不会取消已修改的会议修改前的定时任务,就想办法获取了之前获取的实体类的修改时间和当前在数据库中查到的实体类的修改时间进行比较,如何两个时间相等就会执行发送通知的方法,如果不想等定时任务执行,发送消息的方法不会执行。
期间获取不到CooperativeWorkService用了这个方法
cooperativeWorkService = SpringContextHolder.getBean(CooperativeWorkService.class);
源码如下:
public void taskCycle() {
Timer timer = new Timer();
Calendar calendar = Calendar.getInstance();
Date date = new Date();//当前时间
Date endDate = cooperative.getEndDate();
Date time =cooperative.getStartDate();
Date startTime = new Date(time .getTime() - 600000);
//会议开始时间、会议结束时间与当前时间进行比较,如果当前时间大于开始时间不做会议通知,大于当前时间不做会议结束
int compareTo = date.compareTo(startTime);//当前时间与开始时间比较
int compare = date.compareTo(endDate);//当前时间与结束时间比较
/**
* 指定触发时间
*/
if(compare == -1){
//当前时间小于结束时间
log.info("--------配置会议结束时间定时器开始--------");
calendar.setTime(endDate);
Date endTime = calendar.getTime();
timer.schedule(new RemindTaskEnd(), endTime);
log.info("--------配置会议结束时间定时器结束--------");
}
if(compareTo==-1){
//当前时间小于结束时间的前10分钟
log.info("--------配置会议开始时间定时器开始--------");
timer.schedule(new RemindTaskStart(), startTime);
log.info("--------配置会议开始时间定时器结束--------");
}
}
//会议即将开始
class RemindTaskStart extends TimerTask {
public void run() {
cooperativeWorkService = SpringContextHolder.getBean(CooperativeWorkService.class);
//获取当前会议的开始时间结束时间
Cooperative newCooperative = cooperativeWorkService.getTime(cooperative);
if(null!=newCooperative){
//修改时间比较
Date updateDate = cooperative.getUpdateDate();
Date date = newCooperative.getUpdateDate();
int compareTo = date.compareTo(updateDate);//两个时间比较
if ("0".equals(cooperative.getPostStatus())&& compareTo == 0) {
log.info("--------发送会议通知消息--------");
MessageEntity entity = new MessageEntity();
entity.setType("4");
sendMessage(entity);
}
}
}
}
//会议结束的方法
class RemindTaskEnd extends TimerTask {
public void run() {
cooperativeWorkService = SpringContextHolder.getBean(CooperativeWorkService.class);
Cooperative newCooperative = cooperativeWorkService.getTime(cooperative);
if(null!=newCooperative) {
//修改时间比较
Date updateDate = cooperative.getUpdateDate();
Date date = newCooperative.getUpdateDate();
int compareTo = updateDate.compareTo(date);//两个时间比较
//如果当前会议状态为发布状态 0发布
if ("0".equals(cooperative.getPostStatus()) && compareTo == 0) {
log.info("--------发送会议结束消息--------");
MessageEntity entity = new MessageEntity();
entity.setType("5");
sendMessage(entity);
}
}
}
}
ps:用Timer定时器的弊端就是,项目关闭时,之前设置的所有定时器都会被取消掉,就需要在项目加载时,从数据库中将需要的会议信息取出,重新设置定时器,具体方法如下:
@Component("CooperativeWorkSelect")
@Lazy(false)
public class CooperativeWorkSelect implements InitializingBean {
//InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,
//凡是实现该接口的类,在初始化bean的时都会执行该方法。
@Override
public void afterPropertiesSet() {
FutureTask<String> task = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
start(); // 使用另一个线程来执行该方法,会避免占用Tomcat的启动时间
return "Collection Completed";
}
});
new Thread(task).start();
}
private void start() {
for(int index=0;index<hospital.size();index++){
//读取符合条件的信息
List<Cooperative> list= cooperativeWorkService.readCooperativeWork(cooperative);
//循环取出每一条信息的开始时间和结束时间,调用定时器,发送会议消息
for(int i=0;i<list.size();i++){
cooperative = list.get(i);
FlightTrainTaskController flightTrainTaskController = new FlightTrainTaskController();
flightTrainTaskController.setCooperative(cooperative);
flightTrainTaskController.taskCycle();
}
}
}
}
发送消息的方法,以后会整理更新的