Spring定时任务基本概念及应用实例

一、Spring定时任务的几种实现方式——简介

1、TimerTask

Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行
因为它不能在指定时间执行, 仅仅能让程序依照某一个频度执行,所以TimerTask在实际项目中用的不多。
这里只列一个简单的示例,说明一下Timer的使用方式,不作深入探讨:

1)约定

需要: spring.jar, commons-logging.jar 两个包

2)配置


<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-2.5.xsd">
	
	<bean id="taskService" class="com.zdp.service.TaskService">bean>
	<bean id="scheduledTimerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
		<property name="timerTask" ref="taskService" />
		
		
		
		<property name="period" value="1000" />
		
		
		<property name="delay" value="4000" />
	bean>
	
	<bean id="timerFactoryBean" class="org.springframework.scheduling.timer.TimerFactoryBean">
		<property name="scheduledTimerTasks">
			<list>
				<ref bean="scheduledTimerTask" />
			list>
		property>
	bean>
beans>

3)编码

实现方式就是继承TimerTask 类,重写run方法即可。

/**
 * 定时调度业务类
 */
public class TaskService extends TimerTask {
	
	@Override
	public void run() {
		String currentTime = new SimpleDateFormat("yyy-MM-dd hh:mm:ss").format(new Date());
		System.out.println(currentTime + " 定时任务正在运行...");
	}
}

2、(常用)Spring自带的task

Spring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多。它的好处是,不需要额外引入jar包,配置比较简单,而且功能也比较全面。

3、Quartz

Quartz是一个功能强大的的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行,但是配置起来稍显复杂。

二、应用实例

1、基于注解方式,用sping提供的task实现定时任务

1)配置

在applicationContext.xml中作如下配置
a)配置组件扫描

<context:component-scan base-package="com.xxx.yyy.schedule">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
</context:component-scan>

b)开启task任务注解扫描

<task:annotation-driven/>

成功添加此配置后,applicationContext.xml的命名空间,会添加以下三项内容

xmlns:task="http://www.springframework.org/schema/task
http://www.springframework.org/schema/task 
http://www.springframework.org/schema/task/spring-task-4.1.xsd

如上是最简单的配置,可以满足基础的定时任务需求。

2)编码

在包com.xxx.yyy.schedule下新建定时任务类

@Component
public class WecomMarkTagExecutor {

    private Logger logger = LoggerFactory.getLogger(WecomMarkTagExecutor.class);

    @Autowired
    private WeComMarkTagService weComMarkTagService;

    @Scheduled(cron = "0 0/2 * * * ? ")
    public void task01() {
        try {
            logger.info("wecom打标签任务-start");
            weComMarkTagService.wecomMarkTag();
            logger.info("wecom打标签任务-end");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3)开发中遇到的问题

a)注意spring的组件扫满配置

添加包含的比较简单,就像2)中示例的配置一样。
有时候,定时任务实现类下有些类我们不想放入容器的类,这里放一个通过正则表达式不把指定类放入容器的配置,假设schedule包下有两个定时任务:EveryDayExecutor和WecomMarkTagExecutor,其EveryDayExecutor是其他模块的定时任务,当前模块不能将它放入容器,我们可以作如下配置

<context:component-scan base-package="com.haoys.bdp.*">
        <context:exclude-filter type="regex" expression="com.xxx.yyy.schedule.EveryDayExecutor"/>
</context:component-scan>

这个配置的意思是,扫满schedule包下的组件(放入容器),但排除EveryDayExecutor。

b)注意corn表达式的书写

corn表达式网上很多讲解,一定要注意检查自己写的对不对;我就是由于corn写错了、导致定时任务不能按预想的执行,以为配置错误,改来改去也改不好,不仅浪费时间、还特别影响心情。
注意cron = "0 0/2 * * * ? ",才是每隔2分钟执行一次;
cron = "0 2 * * * ? ",意思是每个小时的第二分钟执行!

c)注意配置

必须开启task注解扫描,才能使@Scheduled注解被扫到,才能让定时任务生效。

2、为定时任务配置线程池

你可能感兴趣的:(后端,spring,java,后端)