一、数据表
1. 邮件信息表
DROP TABLE IF EXISTS `email_title`;
CREATE TABLE `email_title` (
`title_id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(50) NOT NULL COMMENT '标题',
`state` int(2) NOT NULL COMMENT '0:关闭 1:开启',
`bean_class` varchar(50) NOT NULL COMMENT '类名',
`method_name` varchar(50) NOT NULL COMMENT '任务调用的方法名 ',
`cron` varchar(50) NOT NULL COMMENT '定时执行时间',
PRIMARY KEY (`title_id`)
) ENGINE=MyISAM AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
2. 收件人、抄送人信息表
DROP TABLE IF EXISTS `email_receiver_info`;
CREATE TABLE `email_receiver_info` (
`receiver_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL COMMENT '用户名',
`email` varchar(50) NOT NULL COMMENT '邮箱',
`is_delete` int(2) NOT NULL COMMENT '0:删除 1:存在',
`type` int(2) NOT NULL COMMENT '1:收件人 0:抄送人',
`title_id` int(11) NOT NULL,
PRIMARY KEY (`receiver_id`)
) ENGINE=MyISAM AUTO_INCREMENT=96 DEFAULT CHARSET=utf8;
二、在初始化的时候需要全部加载数据库中已经存在的邮件信息
@SuppressWarnings("rawtypes")
public class QuartzJobInitial implements ApplicationListener {
private static Logger LOGGER = LoggerFactory.getLogger(QuartzJobInitial.class);
@Autowired
private EmailTitleManager emailManager;
@Override
public void onApplicationEvent(ApplicationEvent arg0) {
LOGGER.info("----->初始化动作<-----");
try{//获取数据库中所有任务
List jobList = emailManager.getEmailTitle(0);
if (jobList.size() != 0) {
for (EmailTitle job : jobList) {
QuartzUtil.initialJob(job);
}
}
}catch(Exception e){
LOGGER.error(e.getMessage());
}
LOGGER.info("完成");
}
}
三、准备工作
public class SpringContextUtil implements ApplicationContextAware {
// Spring应用上下文环境
private static ApplicationContext applicationContext;
/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
*/
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextUtil.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取对象
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
}
四、设置定时任务执行
public class QuartzUtil {
private static Logger LOGGER = LoggerFactory.getLogger(QuartzUtil.class);
// 公用Scheduler
public static Scheduler scheduler = (StdScheduler) SpringContextUtil.getApplicationContext().getBean("schedulerFactoryBean"); // 同一个对象
public static void initialJob(EmailTitle job){
try {
TriggerKey triggerKey = TriggerKey.triggerKey(job.getMethod_name(), job.getBean_class());
// 获取trigger
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 不存在,创建一个
if (null == trigger) {
createSheduler(job);
} else { // Trigger已存在,那么更新相应的定时设置
updateScheduler(job, triggerKey, trigger);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建一个定时任务
*/
public static void createSheduler(EmailTitle job) throws Exception {
LOGGER.info(" ------ > create");
// 在工作状态可用时,即job_status = 1 ,开始创建
if (job.getState() == 1) {
// 新建一个基于Spring的管理Job类
MethodInvokingJobDetailFactoryBean methodInvJobDetailFB = new MethodInvokingJobDetailFactoryBean();
// 设置Job名称
methodInvJobDetailFB.setName(job.getMethod_name());
// 定义的任务类为Spring的定义的Bean则调用 getBean方法 methodInvJobDetailFB.setTargetObject(SpringContextUtil.getApplicationContext().getBean(job.getBean_class()));
methodInvJobDetailFB.setTargetObject(Class.forName(job.getBean_class()).newInstance());
// 设置任务方法
methodInvJobDetailFB.setTargetMethod(job.getMethod_name());
// 将管理Job类提交到计划管理类
methodInvJobDetailFB.afterPropertiesSet();
//并发设置,不允许邮件并发fasle
methodInvJobDetailFB.setConcurrent(false);
JobDetail jobDetail = methodInvJobDetailFB.getObject();// 动态
jobDetail.getJobDataMap().put("scheduleJob", job);
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCron());
// 按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getMethod_name(), job.getBean_class()).withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger); // 注入到管理类
LOGGER.info(job.getBean_class() + "." + job.getMethod_name() + "创建完毕");
}
}
/**
* 更新相应的定时设置 根据state做相应的处理
*/
public static void updateScheduler(EmailTitle job, TriggerKey triggerKey, CronTrigger trigger)
throws SchedulerException {
LOGGER.info(" ------ > update");
if (job.getState() == 1) {// 0禁用 1启用
if (!trigger.getCronExpression().equalsIgnoreCase(job.getCron())) {
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCron());
// 按新的cron表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
LOGGER.info(job.getBean_class() + "." + job.getMethod_name() + " 更新完毕,目前cron表达式为:" + job.getCron());
}
} else if (job.getState() == 0) {
scheduler.pauseTrigger(triggerKey); // 停止触发器
scheduler.unscheduleJob(triggerKey); // 移除触发器
scheduler.deleteJob(trigger.getJobKey()); // 删除任务
LOGGER.info(job.getBean_class() + "." + job.getMethod_name() + "删除完毕");
}
}
}
五、扫描包