quartz

Quartz是一个彻底由java编写的开源做业调度框架。不要让做业调度这个术语吓着你。尽管Quartz框架整合了许多额外功能, 但就其简易形式看,你会发现它易用得简直让人受不了!。简单地建立一个实现org.quartz.Job接口的java类。Job接口包含惟一的方法:
public void execute(JobExecutionContext context)
throws JobExecutionException;
在你的Job接口实现类里面,添加一些逻辑到execute()方法。一旦你配置好Job实现类并设定好调度时间表,Quartz将密切注意剩余时间。当调度程序肯定该是通知你的做业的时候,Quartz框架将调用你Job实现类(做业类)上的execute()方法并容许作它该作的事情。无需报告任何东西给调度器或调用任何特定的东西。仅仅执行任务和结束任务便可。若是配置你的做业在随后再次被调用,Quartz框架将在恰当的时间再次调用它。

下面说一下quartz的简单使用方法:我这里使用的是maven管理jar  也能够选择其余如gradle。java

导入有关quartz的包web

<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz</artifactId>
			<version>2.2.3</version>
		</dependency>
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz-jobs</artifactId>
			<version>2.2.3</version>
		</dependency>

  而后由于我工程中用的spring管理bean因此还须要导入spring的包spring

<!-- spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>4.3.4.RELEASE</version>
		</dependency>

  spring的版本数据库

<spring.version>4.2.4.RELEASE</spring.version>

  先介绍下我这里用quartz作了什么:  设置了一个定时器 天天零点时候触发,从数据库中查询全部当天生日的用户的邮箱,而后群发祝福邮件。session

quartz为何能作到。只是简单的使用quartz的话,个人理解是这样的。quartz让用户自定义 一个或者多个job ,一至多个trigger,job由使用者自定义内容,trigger用户能够选择两种触发:SimpleTrigger,CronTrigger一般状况下咱们选择使用后者。mvc

若是您须要基于日历的概念而不是按照SimpleTrigger的精确指定间隔进行从新启动的做业启动计划。app

使用CronTrigger,您能够指定号时间表,例如“每周五中午”或“每一个工做日和上午9:30”,甚至“每周一至周五上午9:00至10点之间每5分钟”和1月份的星期五“。框架

即便如此,和SimpleTrigger同样,CronTrigger有一个startTime,它指定什么时候生效,以及一个(可选的)endTime,用于指定什么时候中止计划。maven

SimpleTrigger能够知足的调度需求是:在具体的时间点执行一次,或者在具体的时间点执行,而且以指定的间隔重复执行若干次。好比,你有一个trigger,你能够设置它在2015年1月13日的上午11:23:54准时触发,或者在这个时间点触发,而且每隔2秒触发一次,一共重复5次。ide

下面介绍简单用法,我是用spring管理因此在applicationContext中的配置:

<!-- quartz  -->
    <bean id="sendWishJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject">
            <bean class="com.dabai.jobs.SendBirthdayWish"></bean>
        </property>
        <property name="targetMethod" value="sendWish"></property>
    </bean>
    <!-- quartz调度任务 triggrt-->
    <bean id="sendWishTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <!-- jobDetail -->
        <property name="jobDetail" ref="sendWishJob"></property>
        <!-- 触发时间 -->
        <property name="cronExpression">
            <value>0 0 0 1/1 * ? </value>
        </property>
    </bean>
    <!-- quartz调度工厂 -->
    <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <!-- 注入触发器trigger -->
        <property name="triggers">
            <list>
                <ref bean="sendWishTrigger"/>
            </list>
        </property>
    </bean>

这个是有关发送邮件使用的配置信息 如不须要的话能够忽略

<!-- 邮件配置 -->
    <context:property-placeholder location="classpath:mail.properties" />
    
    <!-- 邮件接口 -->
    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="${mail.smtp.host}"></property>
        <property name="username" value="${mail.smtp.username}"></property>
        <property name="password" value="${mail.smtp.password}"></property>
        <property name="defaultEncoding" value="${mail.smtp.defaultEncoding}"></property>
        <property name="javaMailProperties">
            <props>
                <prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
                <prop key="mail.smtp.timeout">${mail.smtp.timeout}</prop>
            </props>
        </property>
    </bean>

能够看到  上述有关quartz的配置文件中包含三个内容 从上至下能够这样子理解:

1.一个调度  由一个trigger触发 其中一个调度中能够包含多个job,即执行多个任务指定job和其中的方法

2.一个trigger  指i明触发条件和触发的调度<value>0 0 0 1/1 * ? </value>这个表示每一个二十四小时 即一天执行 从零点开始,详情能够参考    cron表达式

3.quartz的trigger list 管理quartz全部触发器的 一个list 说明能够配置多个。

我这里把job放在service层,由于在job中须要查数据库 方便调用

下面是内容

package com.dabai.jobs; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.javamail.JavaMailSender; import com.dabai.service.UserService; import com.dabai.utils.MailSender; /** * @author dabai: * 类说明 查找当日生日的用户 发送生日祝福邮件类 */
public class SendBirthdayWish { @Autowired private UserService userService; @Autowired private JavaMailSender javaMailSender; public void sendWish() throws AddressException{ Calendar date=Calendar.getInstance(); int month=date.get(Calendar.MONTH)+1; int day = date.get(Calendar.DAY_OF_MONTH); List<String>emails=userService.findBirthdayEmails(month,day); if(emails!=null&&emails.size()>0){ String[]array=new String[emails.size()]; List list=new ArrayList(); InternetAddress[]address=null; for (int i=0;i<emails.size();i++) { array[i]=emails.get(i); } for(int i=0;i<array.length;i++){ list.add(new InternetAddress(array[i])); } address=(InternetAddress[]) list.toArray(new InternetAddress[list.size()]); String msg="<h2> hi Dear</h2><br><b><pre>today is"+month+""+day+"日 and it's your birthday! happy birthday to you </pre></b>"; String subject="祝你生日快乐"; MailSender mailsender=new MailSender(); mailsender.sendWish(msg, subject, address, javaMailSender); }else{ System.out.println("today nobody birthday"+new Date().toString()); } } }

下面是dao层的查询代码,我这里是hibernate 

 @Override public List<String> findBirthdayEmails(final int month, final int day) { return  getHibernateTemplate().execute(new HibernateCallback<List<String>>() { @Override public List<String> doInHibernate(Session session) throws HibernateException { String hql="select u.email from User u where MONTH(u.birthday)=? and DAY(u.birthday)=?"; Query query = session.createQuery(hql); query.setInteger(0, month); query.setInteger(1,day); List list = query.list(); if(list!=null&&list.size()>0){ return list; } return null; } }); }