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


    一、什么是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的版本与Spring 的版本有关, Spring 2.x的版本最好用Quartz 1.8.5的,若是 Spring 3.0以上的Quartz 的版本最好用 2.0以上的。

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

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

    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.效果如下

    三、注意事项

    (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实例的属性可以从当前任务传递到下一个任务,做串行。

  • 相关阅读:
    谈我们为什么学不好编程2——你是否已进入“等死模式”?
    JSP使用SmartUpload实现文件上传
    内核模块编程练习
    Vue++:Vue中 关于$emit的用法
    Vue++:Vue 脚手架在vue.config.js文件中配置scss全局变量
    Vue++:Vuecli3.0 脚手架搭建项目
    Java++:七个开源的 Spring Boot 前后端分离项目,一定要收藏!
    MySQL++:SQL 优化的15个小技巧
    RabbitMQ++:RabbitMQ 的队列(Queue)的参数及其含义
    Vue++:Vue 二级路由不显示页面问题
  • 原文地址:https://www.cnblogs.com/cloudml/p/4713566.html
Copyright © 2020-2023  润新知