132

>> 在spring中使用quartz

创建JobDetailBean:

Xml代码 
1.<!-- 通过JobDetailBean实现 --> 
2.<bean name="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean" 
3.    p:jobClass="com.baobaotao.quartz.MyJob" 
4.    p:applicationContextJobDataKey="applicationContext"> 
5.    <property name="jobDataAsMap"> 
6.        <map> 
7.            <entry key="size" value="10" /> 
8.        </map> 
9.    </property> 
10.</bean> 
<!-- 通过JobDetailBean实现 -->
<bean name="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"
    p:jobClass="com.baobaotao.quartz.MyJob"
    p:applicationContextJobDataKey="applicationContext">
    <property name="jobDataAsMap">
        <map>
            <entry key="size" value="10" />
        </map>
    </property>
</bean>在JobDetailBean中有几个属性:

jobClass:类型为Class,实现了Job接口的任务类

beanName:显示指定Bean名称,没啥用处

jobDataAsMap:类型为Map,为任务所对应的JobDataMap提供值。

applicationContextJobDataKey:用户可以通过这个key值将Spring的ApplicationContext的引用保存在里面。

jobListenerNames:类型为String[],指定注册在Schedule中的JobListeners名称。

下面是MyJob定义:

Java代码 
1.import java.util.Map;  
2.   
3.import org.quartz.JobExecutionContext;  
4.import org.quartz.JobExecutionException;  
5.import org.quartz.StatefulJob;  
6.import org.springframework.context.ApplicationContext;  
7.   
8.public class MyJob implements StatefulJob {  
9.    public void execute(JobExecutionContext jctx) throws JobExecutionException {  
10.//      Map dataMap = jctx.getJobDetail().getJobDataMap();  
11.        Map dataMap = jctx.getTrigger().getJobDataMap();  
12.        String size =(String)dataMap.get("size");  
13.        ApplicationContext ctx = (ApplicationContext)dataMap.get("applicationContext");  
14.        System.out.println("size:"+size);  
15.        dataMap.put("size",size+"0");  
16.           
17.        String count =(String)dataMap.get("count");  
18.        System.out.println("count:"+count);  
19.    }  
20.} 
import java.util.Map;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.StatefulJob;
import org.springframework.context.ApplicationContext;

public class MyJob implements StatefulJob {
    public void execute(JobExecutionContext jctx) throws JobExecutionException {
//      Map dataMap = jctx.getJobDetail().getJobDataMap();
        Map dataMap = jctx.getTrigger().getJobDataMap();
        String size =(String)dataMap.get("size");
        ApplicationContext ctx = (ApplicationContext)dataMap.get("applicationContext");
        System.out.println("size:"+size);
        dataMap.put("size",size+"0");
        
        String count =(String)dataMap.get("count");
        System.out.println("count:"+count);
    }
}如果MyJob实现的是StatefulJob,那么里面的JobDataMap为共享公共变量,下次执行的时候还可以获得同样的,这个不是线程安全的,最好都用无状态的Job

>> 利用MethodInvokingJobDetailFactoryBean直接将某个bean的方法定义成任务执行的动作,也就是说不需要定义JobDetail了,直接将某个bean的方法变成job的execute方法:

Xml代码 
1.<!-- 通过封装服务类方法实现 --> 
2.<bean id="jobDetail_1" 
3.    class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" 
4.    p:targetObject-ref="myService" p:targetMethod="doJob" p:concurrent="false" /> 
5.   
6.<bean id="myService" class="com.baobaotao.service.MyService" /> 
<!-- 通过封装服务类方法实现 -->
<bean id="jobDetail_1"
    class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
    p:targetObject-ref="myService" p:targetMethod="doJob" p:concurrent="false" />

<bean id="myService" class="com.baobaotao.service.MyService" />>> 创建Trigger:

* SimpleTriggerBean

Xml代码 
1.<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean" 
2.    p:jobDetail-ref="jobDetail" p:startDelay="1000" p:repeatInterval="2000" 
3.    p:repeatCount="100"> 
4.    <property name="jobDataAsMap"> 
5.        <map> 
6.            <entry key="count" value="10" /> 
7.        </map> 
8.    </property> 
9.</bean> 
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"
    p:jobDetail-ref="jobDetail" p:startDelay="1000" p:repeatInterval="2000"
    p:repeatCount="100">
    <property name="jobDataAsMap">
        <map>
            <entry key="count" value="10" />
        </map>
    </property>
</bean>SimpleTriggerBean在SimpleTrigger基础上增加了以下属性:

jobDetail:对应的JobDetail

beanName:默认为bean的id,不过之前用beanName属性显示指定了名称的也可以用这个

jobDetailAsMap:以Map类型为Trigger关联的JobDataMap提供值

startDelay:延迟多少时间触发,单位为毫秒,默认为0

triggerListenerNames:类型为String[],不解释了

>> CronTriggerBean

Xml代码 
1.<bean id="checkImagesTrigger" 
2.      class="org.springframework.scheduling.quartz.CronTriggerBean" 
3.      p:jobDetail-ref="jobDetail" 
4.      p:cronExpression="0/5 * * * * ?"/> 
<bean id="checkImagesTrigger"
      class="org.springframework.scheduling.quartz.CronTriggerBean"
      p:jobDetail-ref="jobDetail"
      p:cronExpression="0/5 * * * * ?"/>>> 创建Scheduler

spring提供了ScheduleFactoryBean,可以在spring容器启动后,Scheduler自动开始工作,而在spring容易关闭前,自动关闭Scheduler

Xml代码 
1.<bean id="scheduler" 
2.    class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 
3.    <property name="triggers"> 
4.        <list> 
5.            <ref bean="simpleTrigger" /> 
6.        </list> 
7.    </property> 
8.    <property name="schedulerContextAsMap"> 
9.        <map> 
10.            <entry key="timeout" value="30" /> 
11.        </map> 
12.    </property> 
13.    <property name="configLocation" value="classpath:com/baobaotao/quartz/quartz.properties" /> 
14.    <property name="quartzProperties"> 
15.        <props> 
16.            <prop key="org.quartz.threadPool.class"> 
17.                org.quartz.simpl.SimpleThreadPool  
18.            </prop> 
19.            <prop key="org.quartz.threadPool.threadCount">10</prop> 
20.        </props> 
21.    </property> 
22.</bean> 
<bean id="scheduler"
    class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="simpleTrigger" />
        </list>
    </property>
    <property name="schedulerContextAsMap">
        <map>
            <entry key="timeout" value="30" />
        </map>
    </property>
    <property name="configLocation" value="classpath:com/baobaotao/quartz/quartz.properties" />
    <property name="quartzProperties">
        <props>
            <prop key="org.quartz.threadPool.class">
                org.quartz.simpl.SimpleThreadPool
            </prop>
            <prop key="org.quartz.threadPool.threadCount">10</prop>
        </props>
    </property>
</bean>SchedulerFactoryBean还拥有一些常见的属性:

* calendars:类型为Map,通过该属性向Scheduler注册Calendar

* jobDetails:类型为JobDetail[],注册JobDetail

* autoStartup:是否马上启动Scheduler,默认为true

* startupDelay:延迟多少秒启动Scheduler

* dataSource:当需要数据库持久化任务调度数据时候用到

* transactionManager:当配一个dataSource后,应该同步配置这个

* nonTransactionalDataSource:无事务的数据源

* quartzProperties:允许用户在spring中定义Quartz属性,覆盖quartz.properties文件中的定义

>> spring对于JDK5中的Executor的支持

JDK5本身提供的ThreadPoolExecutor类实现了Executor和ExecutorService这两个接口,它使用一个线程池对提交的任务进行调度,对于需要处理数量巨大的短小并发任务如Web服务器、数据库服务器、邮件服务器之类的应用程序需要处理大量来自远程的大量短小任务,采用线程池可以带来明显好处。

ScheduledThreadPoolExecutor是ThreadPoolExecutor的子类,并实现了ScheduledExecutorService接口,添加了对任务的调度功能,该类明显优于JDK1.3中的Timer,因为在内部用线程池,对每次到来的任务用一个新线程去执行,而不是像TImer那么,要等这个任务执行完,才能执行下一个任务,很好的解决了Timer经常出现的时间漂移、任务挤压等问题。

工厂类Executors有很多方法很方便的创建这些线程池:

* public static  ExecutorService newFixedThreadPool(int nThreads):固定数目的线程数量

* public static ExecutorService newCachedThreadPool():线程池动态的,不够就创建新的,长时间不用就回收

* public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory) :创建一个线程池,可以在指定延迟后运行或定期执行任务

Java代码 
1.import org.springframework.core.task.SimpleAsyncTaskExecutor;  
2.import org.springframework.core.task.TaskExecutor;  
3.   
4.public class ExecutorExample {  
5.    private TaskExecutor executor;  
6.    public void setExecutor(TaskExecutor executor) {  
7.        this.executor = executor;  
8.    }  
9.    public void executeTasks() {  
10.        for (int i = 0; i < 6; i++) {  
11.            executor.execute(new SimpleTask("task" + i));  
12.        }  
13.    }  
14.    public static void main(String[] args) {  
15.        ExecutorExample ee = new ExecutorExample();  
16.        ee.setExecutor(new SimpleAsyncTaskExecutor());  
17.        ee.executeTasks();  
18.    }  
19.}  
20.class SimpleTask implements Runnable {  
21.    private String taskName;  
22.    public SimpleTask(String taskName) {  
23.        this.taskName = taskName;  
24.    }  
25.    public void run() {  
26.        System.out.println("do " + taskName + "... in Thread:" 
27.                + Thread.currentThread().getId());  
28.    }  
29.} 
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;

public class ExecutorExample {
    private TaskExecutor executor;
    public void setExecutor(TaskExecutor executor) {
        this.executor = executor;
    }
    public void executeTasks() {
        for (int i = 0; i < 6; i++) {
            executor.execute(new SimpleTask("task" + i));
        }
    }
    public static void main(String[] args) {
        ExecutorExample ee = new ExecutorExample();
        ee.setExecutor(new SimpleAsyncTaskExecutor());
        ee.executeTasks();
    }
}
class SimpleTask implements Runnable {
    private String taskName;
    public SimpleTask(String taskName) {
        this.taskName = taskName;
    }
    public void run() {
        System.out.println("do " + taskName + "... in Thread:"
                + Thread.currentThread().getId());
    }
}

你可能感兴趣的:(spring)