1. 程式人生 > >Spring中定時任務

Spring中定時任務

    需求:每天上午9點執行任務

    使用Spring框架實現定時任務的編寫,這裡有兩種方法.

     一timer定時器

public class TestListen implements ServletContextListener {
	
	private Timer timer = null;
	//時間間隔(一天)  
	private static final long PERIOD_DAY = 24 * 60 * 60 * 1000;
	@Override
	public void contextDestroyed(ServletContextEvent arg0) {
		System.out.println("task stop...............");
		timer.cancel();
	}

	@Override
	public void contextInitialized(ServletContextEvent arg0) {
		System.out.println("task statr.............");
		Calendar calendar = Calendar.getInstance();  
	    calendar.set(Calendar.HOUR_OF_DAY, 9); //每天9點  
	    calendar.set(Calendar.MINUTE, 0);  
	    calendar.set(Calendar.SECOND, 0);  
	    Date date=calendar.getTime(); //第一次執行定時任務的時間  
	    //如果第一次執行定時任務的時間 小於當前的時間  
	    //此時要在 第一次執行定時任務的時間加一天,以便此任務在下個時間點執行。如果不加一天,任務會立即執行。  
	    if (date.before(new Date())) {  
	        date = this.addDay(date, 1);  
	    }  
	    timer = new Timer(true);
	    //安排指定的任務在指定的時間開始進行重複的固定延遲執行。  
	    timer.schedule(new TestTask(),date,PERIOD_DAY);
	}
	
	// 增加或減少天數  
	public Date addDay(Date date, int num) {  
	    Calendar startDT = Calendar.getInstance();  
	    startDT.setTime(date);  
	    startDT.add(Calendar.DAY_OF_MONTH, num);  
	    return startDT.getTime();  
	}  
}
public class TestTask extends TimerTask {
	@Override
	public void run() {
		System.out.println("這是定時任務==============================="+new Date().getSeconds());

	}

}

    具體步驟:

    1.一個TestListen繼承 ServletContextListener,重寫 contextInitialized()方法,專案啟動時,呼叫 contextInitialized()方法.

    2.在contextInitialized()方法中使用 timer.schedule(new TestTask(),date,PERIOD_DAY) 按規定時間 呼叫具體任務類TestTask.

    3. TFPTask 繼承 TimerTask 重寫 run() 方法, 定時任務具體的程式碼 在 run() 方法裡.

參考文章:

    二、Spring 整合Quartz框架

在Spring 的配置檔案 quartz-task.xml 中 配置:

 <bean id="resetPidTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
     <description>每天日重置執行緒池執行任務</description>
		<property name="jobDetail">
	    <bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject">
	<!-- 	呼叫的具體類 -->
                     <bean class="com.cares.ceseas.service.timetask.SendEmailForCard" />
	         </property>
	<!-- 	呼叫的具體類中的方法 run() -->
	         <property name="targetMethod"><value>run</value></property>
	    </bean>
	</property>
	<property name="cronExpression">
<!-- 	    <value>0 0 9 * * ?</value> -->
<!-- 		每10秒執行一次 -->
<!-- 	    <value>0/10 * * * * ?</value> -->
	    <value>0 */1 * * * ?</value>
	 </property>
  </bean>
	 
  <bean id="schedulerFactory" autowire="no"
	class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
	<description>定時觸發器 設定</description>
	    <property name="triggers">
	        <list>
	           <ref local="resetPidTrigger"/> 
	        </list>
	    </property>
   </bean> 
public class SendEmailForCard {
		
	public void run() {
        	System.out.println("Quartz的任務排程!!!傳送郵件-=====--==="+new Date().getSeconds());
	}
}

參考文章:

執行多個定時任務

一 、使用 ScheduledExecutorService 併發包,開啟多個執行緒執行 多個定時任務

public class SummaryListen implements ServletContextListener {
	/**
	 * 使用工廠方法初始化一個ScheduledThreadPool
	 */
	ScheduledExecutorService newScheduledThreadPool = Executors
			.newScheduledThreadPool(10);
	Logger logger = Logger.getLogger(SummaryListen.class.getName());

	@Override
	public void contextDestroyed(ServletContextEvent arg0) {
		newScheduledThreadPool.shutdown();
	}

	@Override
	public void contextInitialized(ServletContextEvent arg0) {
        
		Future<?>f1 = newScheduledThreadPool.scheduleAtFixedRate(
				new Task1(), 0, 15, TimeUnit.MINUTES);
		Future<?>f2 = newScheduledThreadPool.scheduleAtFixedRate(
				new Task2(), 0, 24, TimeUnit.HOURS);
		Future<?>f3 = newScheduledThreadPool.scheduleAtFixedRate(
                    new Task3(),0, 5, TimeUnit.MINUTES);
		Future<?>f4 = newScheduledThreadPool.scheduleAtFixedRate(
                    new Task4(),0, 10, TimeUnit.MINUTES);
                ......
		try {
			f1.get();
			f2.get();
			f3.get();
			f4.get();
			......
		} catch (InterruptedException e) {
			logger.error(e.getMessage(), e);
		} catch (ExecutionException e) {
			logger.error(e.getMessage(), e);
		}
	}

}
public class Task1 extends TimerTask {
	Logger logger = Logger.getLogger(Task1.class.getName());

	@Override
	public void run() {
		logger.info("*** Task1 START!! *****************");
		......
	}
}

、Spring 整合Quartz框架,quartz-task.xml配置多個 Job

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"
	default-lazy-init="false">
<!-- 執行緒池 -->
	<bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> 
		<property name="corePoolSize" value="10" /> 
		<property name="maxPoolSize" value="100" /> 
		<property name="queueCapacity" value="500" />
	</bean>
	<!--每日任務 -->
<!-- Job1 -->
	<bean id="job1" class="com.care.service.Job1"></bean>
	<bean id="Job1Detail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject" ref="job1" />
		<property name="targetMethod" value="execute" />
	</bean>
<!-- 排程器1 -->
	<bean id="Job1Trigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
		<property name="jobDetail" ref="Job1Detail" />
		<property name="cronExpression" value="0/11 * * * * ?" />
	</bean>
<!-- Job2 -->
	<bean id="job2" class="com.care.service.Job2"></bean>
	<bean id="Job2Detail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject" ref="job2" />
		<property name="targetMethod" value="execute" />
	</bean>
	<bean id="Job2Trigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
		<property name="jobDetail" ref="Job2Detail" />
		<property name="cronExpression" value="0/21 * * * * ?" />
	</bean>
	
<!-- 啟動觸發器的配置 -->
    <bean name="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 
       <!-- 通過applicationContextSchedulerContextKey屬性配置spring上下文 -->    
        <property name="applicationContextSchedulerContextKey">    
            <value>applicationContext</value>    
        </property>   
        <property name="triggers">  
			<list>   
				<ref bean="Job1Trigger" /> 
				<ref bean="Job2Trigger" />   
			</list> 
		</property> 
    	<property name="taskExecutor" ref="executor" /> 
   	</bean> 
</beans>

在Spring核心配置檔案application.xml 匯入定時任務的配置檔案

<import resource="quartz-task.xml" />

、Quartz註解

在Spring核心配置檔案application.xml 配置

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:task="http://www.springframework.org/schema/task"
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.2.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
......
  
<!-- 定時任務 註解方式-->
<task:scheduler id="tmTaskScheduler" pool-size="1"/>
<task:annotation-driven scheduler="tmTaskScheduler" mode="proxy"/>

......
@Service
public class Job1 {
	
@Scheduled(cron="0/10 * * * * ? ")
public void execute(){
	System.out.println("定時任務 1 ------------------------------------");
    }
}
@Service
public class Job2 {
	
@Scheduled(cron="0/10 * * * * ? ")
public void execute(){
	System.out.println("定時任務 2 ------------------------------------");
    }
}