在上一篇博客SpringCloud传文件讲到服务会缓存一堆中间文件, 清理的时机包含合并文件后或者超时。 假设服务器只保存7天,超过7天的中间文件要被清除, 该如何实现这个功能呢? 当然是定时任务了。
顾名思义, 定时任务就是每隔一段时间或者在某一时刻执行一个函数。
在SpringCloud微服务框架内, 即使是一个接口也可以做成一个独立的服务,定时任务也不例外。 以删中间为例,定时任务要读数据库找到超时的记录, 删除对应的文件并更新数据表状态位。 为了讲解方便,仍使用MyBatis基础-增删改查为例。
新建一个AndroidStudio工程, 命名为SpringCloudSchedule。 在pom.xml添加对mybatis的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>springcloudschedule</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SpringCloudSchedule</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- 访问数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在application.yml里添加注册中心、服务端口、mybatis配置等。
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
server:
port: 10110
spring:
application:
name: service-shedule-gc #建议以功能命名,每个定时任务做个微服务
mybatis:
mapper-locations: classpath:mybatis/mappers/*.xml #设置mapper文件目录
config-location: classpath:mybatis/mybatis-confix.xml #默认配置文件目录
在入口类添加@EnableScheduling打开定时任务功能,
@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@EnableEurekaClient //向Eureka服务注册
@EnableScheduling //使能定时任务
@MapperScan("com.springms.cloud.mapper.**")
public class SpringCloudScheduleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudScheduleApplication.class, args);
System.out.println("-------------定时任务SpringCloudSchedule已启动-------------");
}
}
新建Java类并添加@Component注解, 需要做定时任务的函数要添加@Scheduled注解,支持fixedRate、cron和fixedDelay等参数。其中cron参数较常用, 它可以设置某个时刻触发执行定时任务, cron表达式包含至少6个(也可能7个)由空格分隔的时间元素。
@Component
public class ScheduledTask {
private static final Logger logger = LoggerFactory.getLogger(ScheduledTask.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-DD HH:mm:ss");
/**
* 每隔5秒执行, 单位:ms。
*/
@Scheduled(fixedRate = 5000)
public void testFixRate() {
System.out.println("我每隔5秒冒泡一次:" + dateFormat.format(new Date()));
}
@Scheduled(cron = "0 0 1 * * ?") //每天凌晨1点执行
public void testMyBatis() {
System.out.println("我每天凌晨1点开始执行");
SqlSession sqlSession = null;
try {
sqlSession = SqlSessionFactoryUtil.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> list = userDao.findUsersAll(); //执行SQL语句:select * from user
//定时任务可以做耗时操作,包括做生成数据库报表、文件IO等等需要定时执行的逻辑
if (list != null) {
System.out.println("假装在处理定时任务,例如复杂耗时的SQL操作、文件IO什么的" );
} else {
System.out.println("我什么事都不用做,等待下次再说吧");
}
} catch (Exception ex) {
} finally {
if (sqlSession != null ) {
sqlSession.close();
}
}
}
}
为了测试方便,修改了testMyBatis函数的注解让它执行起来, 可以看到能够读取数据库记录。
CRON参数含义(按照先后顺序):
字段 | 值范围 | 特殊字符 |
秒 | 0-59 | , - * / |
分 | 0-59 | , - * / |
小时 | 0-23 | , - * / |
日期 | 1-31 | , - * ? / L W C |
月份 | 1-12 或者 JAN-DEC | , - * / |
星期 | 1-7 或者 SUN-SAT | , - * ? / L C # |
年(可选) | 留空, 1970-2099 | , - * / |
完整代码: http://download.csdn.net/download/brycegao321/10160174