基于Quartz实现简单的定时发送邮件

时间:2021-03-20 07:56:31

一、什么是Quartz

Quartz 是一个轻量级任务调度框架,只需要做些简单的配置就可以使用;它可以支持持久化的任务存储,即使是任务中断或服务重启后,仍可以继续运行。Quartz既可以做为独立的应用提供服务,也可以和其他应用集成一起使用。

核心概念:

1、Job
表示一个工作,要执行的具体内容。此接口中只有一个方法
void execute(JobExecutionContext context) 
2、JobDetail
JobDetail表示一个具体的可执行的调度程序,Job是这个可执行程调度程序所要执行的内容,另外JobDetail还包含了这个任务调度的方案和策略。 
3、Trigger代表一个调度参数的配置,什么时候去调。 
4、Scheduler代表一个调度容器,一个调度容器中可以注册多个JobDetail和Trigger。当Trigger与JobDetail组合,就可以被Scheduler容器调度了。

Quartz的类关系图:

基于Quartz实现简单的定时发送邮件

注意:Quartz的版本与Spring 的版本有关, Spring 2.x的版本最好用Quartz 1.8.5的,若是 Spring 3.0以上的Quartz 的版本最好用 2.0以上的。

二、基于Sping+Quartz实现简单的JAVA邮件发送

1.创建一个Java(Web)工程

基于Quartz实现简单的定时发送邮件

2.实现SimpleMail、MailJob、EmailScheduler类

SimpleMail:

 

 1 package com.quartz.mail;
2
3 import org.apache.commons.mail.EmailException;
4 import org.apache.commons.mail.SimpleEmail;
5
6 import javax.mail.internet.AddressException;
7 import javax.mail.internet.InternetAddress;
8 import java.util.ArrayList;
9 import java.util.Date;
10 import java.util.List;
11
12 /**
13 * Created by xiwu.xxw on 2015/8/8.
14 */
15 public class SimpleMail {
16 private SimpleEmail mail;
17
18 /**
19 * 初始化一封邮件,暂不支持富媒体和附件
20 * @param receivers 邮件的接收者
21 * @param subject 邮件主题
22 * @param content 邮件内容
23 * @throws EmailException
24 * @throws AddressException
25 */
26 public SimpleMail(List<String> receivers,String subject,String content) throws EmailException, AddressException {
27 mail=new SimpleEmail();
28 mail.setCharset("UTF-8");
29 List<InternetAddress> toList=new ArrayList<InternetAddress>();
30 for(String receiver: receivers){
31 toList.add(new InternetAddress(receiver));
32 }
33 mail.setTo(toList);
34 mail.setSubject(subject);
35 mail.setContent(content, "text/html;charset=utf-8");
36 }
37
38 /**
39 * 发送邮件
40 * @param from 发送方邮件地址
41 * @param password 发送授权码
42 * @return
43 * @throws EmailException
44 */
45 public String sendEmail(String from,String password) throws EmailException {
46 mail.setFrom(from);
47 //发送方邮箱权限认证,发送方邮箱须开通SMTP/POP/IMAP功能
48 mail.setAuthentication(from, password);
49 mail.setHostName("smtp." + from.split("@")[1]);
50 mail.setSentDate(new Date());
51 return mail.send();
52 }
53 }

 

MailJob:

 1 package com.quartz.job;
2
3 import com.quartz.mail.SimpleMail;
4 import org.quartz.JobDataMap;
5 import org.quartz.JobExecutionContext;
6 import org.quartz.JobExecutionException;
7 import org.springframework.scheduling.quartz.QuartzJobBean;
8
9 import java.util.List;
10
11 /**
12 * Created by xiwu.xxw on 2015/8/8.
13 */
14 public class MailJob extends QuartzJobBean {
15 /**
16 * 执行Job任务
17 * @param context
18 * @throws JobExecutionException
19 */
20 @Override
21 protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
22 JobDataMap map=context.getJobDetail().getJobDataMap();
23 try {
24 SimpleMail mail=new SimpleMail((List<String>) map.get("receivers"),map.getString("subject"),map.getString("content"));
25 String result=mail.sendEmail(map.getString("from"), map.getString("password"));
26 System.out.println(result);
27 } catch (Exception e) {
28 e.printStackTrace();
29 }
30 }
31 }

EmailScheduler:

 1 package com.quartz.scheduler;
2
3 import org.quartz.SchedulerException;
4 import org.quartz.impl.StdScheduler;
5 import org.springframework.context.support.ClassPathXmlApplicationContext;
6 import org.springframework.scheduling.quartz.CronTriggerBean;
7 import org.springframework.scheduling.quartz.JobDetailBean;
8 import org.springframework.scheduling.quartz.SimpleTriggerBean;
9
10 import java.util.ArrayList;
11 import java.util.List;
12
13 /**
14 * Created by xiwu.xxw on 2015/8/8.
15 */
16 public class EMailScheduler {
17 public static void main(String[] args) throws SchedulerException {
18 //收件人
19 List<String> receivers=new ArrayList<String>();
20 receivers.add("xxxxx@qq.com");
21 receivers.add("xxxxx@126.com");
22 receivers.add("xxxxx@163.com");
23
24 ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
25 //邮件JobBean
26 JobDetailBean mailJob= (JobDetailBean) context.getBean("mailJob");
27 mailJob.setName("mailJob");
28 mailJob.setGroup("textEmail");
29 // 指明任务就算没有绑定Trigger仍保留在Quartz的JobStore中
30 //mailJob.setDurability(true);
31 mailJob.getJobDataMap().put("receivers",receivers);
32 mailJob.getJobDataMap().put("subject","基于Quartz实现邮件发送");
33 mailJob.getJobDataMap().put("content","本程序基于Quartz实现了定时群发邮件的功能,目前只支持文本发送!");
34
35
36 //发送邮件任务的SimpleTrigger触发器
37 SimpleTriggerBean simpleTrigger= (SimpleTriggerBean) context.getBean("SimpleTrigger");
38
39 //发送邮件任务调度器
40 StdScheduler scheduler= (StdScheduler) context.getBean("startQuartzTask");
41 //加入一个任务到Quartz框架中, 并与simpleTrigger关联
42 //Quartz会自动校正与设置simpleTrigger的JobName与JobGroup属性
43 scheduler.scheduleJob(mailJob,simpleTrigger);
44
45 //发送邮件任务的CronTrigger触发器
46 CronTriggerBean croTrigger= (CronTriggerBean) context.getBean("CronTrigger");
47 //将发送邮件任务的触发器与邮件任务关联并注册到调度器
48 croTrigger.setJobName("mailJob");
49 croTrigger.setJobGroup("textEmail");
50 //因为任务已在上一条语句中已加入, 所以不能再使用scheduleJob(JobDetail, Trigger)
51 scheduler.scheduleJob(croTrigger);
52
53 try {
54 //开始调度
55 scheduler.start();
56 } catch (SchedulerException e) {
57 e.printStackTrace();
58 }
59 }
60 }

3.配置applicationContext.xml

 1 <?xml version="1.0" ?>
2 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
3 xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
4 xmlns:tx="http://www.springframework.org/schema/tx"
5 xsi:schemaLocation="
6 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
9 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
10 ">
11
12 <bean id="dataEditor" class="org.springframework.beans.propertyeditors.CustomDateEditor">
13 <constructor-arg>
14 <bean class="java.text.SimpleDateFormat">
15 <constructor-arg value="yyyy-MM-dd H:m:s"/>
16 </bean>
17 </constructor-arg>
18 <constructor-arg value="true"/>
19 </bean>
20
21 <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
22 <property name="customEditors">
23 <map>
24 <entry key="java.util.Date">
25 <ref local="dataEditor"/>
26 </entry>
27 </map>
28 </property>
29 </bean>
30
31 <bean id="mailJob" class="org.springframework.scheduling.quartz.JobDetailBean">
32 <property name="jobClass">
33 <value>com.quartz.job.MailJob</value>
34 </property>
35 <property name="jobDataAsMap">
36 <map>
37 <entry key="from">
38 <value>xxxxxxx@126.com</value>
39 </entry>
40 <entry key="password">
41 <value>uebbqvlizrywzhei</value>
42 </entry>
43 </map>
44 </property>
45 </bean>
46
47 <bean id="SimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
48 <property name="startDelay">
49 <value>5000</value>
50 </property>
51 <property name="repeatInterval">
52 <value>120000</value>
53 </property>
54 <property name="repeatCount">
55 <value>3</value>
56 </property>
57 </bean>
58
59 <bean id="CronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
60 <property name="cronExpression">
61 <value>0 25/2 17 8 8 ? 2015</value>
62 </property>
63 <property name="endTime" value="2015-08-08 17:30:00"/>
64 </bean>
65
66 <bean id="startQuartzTask" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
67 </beans>

4.效果如下

基于Quartz实现简单的定时发送邮件

三、注意事项

(1)Job被创建后,可以保存在Scheduler中,与Trigger是独立的,同一个Job可以有多个Trigger;这种松耦合的另一个好处是,当与Scheduler中的Job关联的trigger都过期时,可以配置Job稍后被重新调度,而不用重新定义Job;还有,可以修改或者替换Trigger,而不用重新定义与之关联的Job。

(2)将Job和Trigger注册到Scheduler时,可以为它们设置key,配置其身份属性。Job和Trigger的key(JobKey和TriggerKey)可以用于将Job和Trigger放到不同的分组(group)里,然后基于分组进行操作。同一个分组下的Job或Trigger的名称必须唯一,即一个Job或Trigger的key由名称(name)和分组(group)组成。

(3)在Quartz中,如果实现org.quartz.Job接口,那么这个job是stateless的,job实例的参数不能在多个任务之间共享,做并发,如果实现org.quartz.StatefulJob,这个job是个单例的,job实例的属性可以从当前任务传递到下一个任务,做串行。