寫了一個項目需要在一定時間觸發(fā)發(fā)送消息的接口
需求是:
①在會議開始前10分鐘發(fā)送會議邀請
②在會議開始時發(fā)送參會通知
③在會議結(jié)束時發(fā)送會議結(jié)束通知
我的思路如下:
在新增會議的時候獲取參會時間,到達(dá)各個時間點自動調(diào)用發(fā)送消息的接口就可以了
cooperative是我會議的實體類
由于考慮到會議時間是可以修改的,但是我不會取消已修改的會議修改前的定時任務(wù),就想辦法獲取了之前獲取的實體類的修改時間和當(dāng)前在數(shù)據(jù)庫中查到的實體類的修改時間進(jìn)行比較,如何兩個時間相等就會執(zhí)行發(fā)送通知的方法,如果不想等定時任務(wù)執(zhí)行,發(fā)送消息的方法不會執(zhí)行。
期間獲取不到CooperativeWorkService用了這個方法
cooperativeWorkService = SpringContextHolder.getBean(CooperativeWorkService.class);
源碼如下:
public void taskCycle() {
Timer timer = new Timer();
Calendar calendar = Calendar.getInstance();
Date date = new Date();//當(dāng)前時間
Date endDate = cooperative.getEndDate();
Date time =cooperative.getStartDate();
Date startTime = new Date(time .getTime() - 600000);
//會議開始時間、會議結(jié)束時間與當(dāng)前時間進(jìn)行比較,如果當(dāng)前時間大于開始時間不做會議通知,大于當(dāng)前時間不做會議結(jié)束
int compareTo = date.compareTo(startTime);//當(dāng)前時間與開始時間比較
int compare = date.compareTo(endDate);//當(dāng)前時間與結(jié)束時間比較
/**
* 指定觸發(fā)時間
*/
if(compare == -1){
//當(dāng)前時間小于結(jié)束時間
log.info("--------配置會議結(jié)束時間定時器開始--------");
calendar.setTime(endDate);
Date endTime = calendar.getTime();
timer.schedule(new RemindTaskEnd(), endTime);
log.info("--------配置會議結(jié)束時間定時器結(jié)束--------");
}
if(compareTo==-1){
//當(dāng)前時間小于結(jié)束時間的前10分鐘
log.info("--------配置會議開始時間定時器開始--------");
timer.schedule(new RemindTaskStart(), startTime);
log.info("--------配置會議開始時間定時器結(jié)束--------");
}
}
//會議即將開始
class RemindTaskStart extends TimerTask {
public void run() {
cooperativeWorkService = SpringContextHolder.getBean(CooperativeWorkService.class);
//獲取當(dāng)前會議的開始時間結(jié)束時間
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("--------發(fā)送會議通知消息--------");
MessageEntity entity = new MessageEntity();
entity.setType("4");
sendMessage(entity);
}
}
}
}
//會議結(jié)束的方法
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);//兩個時間比較
//如果當(dāng)前會議狀態(tài)為發(fā)布狀態(tài) 0發(fā)布
if ("0".equals(cooperative.getPostStatus()) && compareTo == 0) {
log.info("--------發(fā)送會議結(jié)束消息--------");
MessageEntity entity = new MessageEntity();
entity.setType("5");
sendMessage(entity);
}
}
}
}
ps:用Timer定時器的弊端就是,項目關(guān)閉時,之前設(shè)置的所有定時器都會被取消掉,就需要在項目加載時,從數(shù)據(jù)庫中將需要的會議信息取出,重新設(shè)置定時器,具體方法如下:
@Component("CooperativeWorkSelect")
@Lazy(false)
public class CooperativeWorkSelect implements InitializingBean {
//InitializingBean接口為bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,
//凡是實現(xiàn)該接口的類,在初始化bean的時都會執(zhí)行該方法。
@Override
public void afterPropertiesSet() {
FutureTask<String> task = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
start(); // 使用另一個線程來執(zhí)行該方法,會避免占用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);
//循環(huán)取出每一條信息的開始時間和結(jié)束時間,調(diào)用定時器,發(fā)送會議消息
for(int i=0;i<list.size();i++){
cooperative = list.get(i);
FlightTrainTaskController flightTrainTaskController = new FlightTrainTaskController();
flightTrainTaskController.setCooperative(cooperative);
flightTrainTaskController.taskCycle();
}
}
}
}
發(fā)送消息的方法,以后會整理更新的