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。

导入有关quartz的包

  <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 -->
		<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做了什么:  设置了一个定时器 每天零点时候触发,从数据库中查询所有当天生日的用户的邮箱,然后群发祝福邮件。

quartz为什么能做到。只是简单的使用quartz的话,我的理解是这样的。quartz让用户自定义 一个或者多个job ,一至多个trigger,job由使用者自定义内容,trigger用户可以选择两种触发:SimpleTrigger,CronTrigger通常情况下我们选择使用后者。

如果您需要基于日历的概念而不是按照SimpleTrigger的精确指定间隔进行重新启动的作业启动计划。

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

即使如此,和SimpleTrigger一样,CronTrigger有一个startTime,它指定何时生效,以及一个(可选的)endTime,用于指定何时停止计划。

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

下面介绍简单用法,我是用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;
            }
        });
        
    }

 

posted @ 2019-03-27 15:25  落楝花  阅读(867)  评论(0编辑  收藏  举报

乘兴而来