Spring自带的@Scheduled注解
简单的定时任务控制,注解使用spring自带定时任务就可以完成啦,定时任务类也是由Spring管理,所以可以正常使用IOC自动注入其他的类.
具体原理没有深究哈,日后学习Spring源码的时候再详细了解吧.这里只说怎么应用.
1. 在主启动类上面加@EnableScheduling,开启定时任务
@SpringBootApplication
@EnableScheduling
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
2. 定时任务类
这个@Slf4j是用了lombok自动生成了一个log,没有配置的话可以直接创建一个log
这里是初始延迟1s,然后以固定3s的频率执行,在方法中sleep了5s.
也可以直接使用cron表达式,这里简单示例
@Component
@Slf4j
public class TestScheduled {
@Scheduled(fixedRateString = "3000", initialDelay = 1000)
public void printTrace() {
log.info("printTrace---------------------------------------- at" + LocalTime.now());
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
会看到程序的打印输出的时间大概是这样:
printTrace--- at11:30:03.713384
printTrace--- at11:30:10.923850
printTrace--- at11:30:17.945608
printTrace--- at11:30:24.957384
你可能会疑问,这时间间隔并不是3s啊,这什么玩意?
这是因为Scheduled默认是同步执行的,下次一任务来的时候,发现上一个还没执行完,那就等它执行完再执行.
3. 开启异步执行定时任务,在主启动类上面加@EnableScheduling
然后在TestScheduled类上加注解@Async
然后我们打印一下当前线程,便于观察:
log.info("printTrace-- at" + LocalTime.now() + "in thread:" + Thread.currentThread().getName());
就会发现每隔3s打印一次,8个线程循环执行,大概就是默认线程池的coreSize是8了,以后再详细研究.
4. 设置异步执行定时任务的线程池大小
在主启动类中,或者其他配置类中,加入一个Bean:
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.initialize();
// 试了下这个,不太好使,先不深入探究了..
/*Executor executor = new ThreadPoolExecutor(
2
, 10
, 2000
, TimeUnit.MILLISECONDS
, new ArrayBlockingQueue<>(100)
, Executors.defaultThreadFactory()
, new ThreadPoolExecutor.AbortPolicy()
);*/
return executor;
}
Spring中使用quartz
先参照W3C了解quartz的基本用法.
然后会发现,应用到Spring项目中,Job中不能使用Spring管理的对象,IOC自动注入类.所以需要稍微做点配置.
1. pom.xml引入依赖:
<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>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
2. quartz.properties配置:
定时任务的信息一般会配置存储在数据库中,demo也可以存储在内存中
内存存储quartz.properties:
org.quartz.scheduler.instanceName=Test-testScheduler
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
数据库存储quartz-prod.properties:
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName: TestScheduler
org.quartz.scheduler.instanceId: AUTO
org.quartz.scheduler