近日项目开发中需要在每天日定时分析一次前一天的日志信息,借此机会整理了一下在spring环境下几种定时任务的实现方式:
分类
- java.util.Timer
用于管理在后台执行的延迟任务或周期性任务,可以按照固定频率或固定延迟时间执行。
- Quartz
一个轻量级的Java库,几乎可以集成到任何应用系统中的框架。- task
spring3.0自带的Timer,使用更加简便。
用法
-
java自带Timer实现
以下案例schedule()方法内的第一个参数为
TimerTask task
,为需要执行的任务,第二个参数为long delay
为延时启动时间,第三个参数long period
为执行周期。程序效果为2s后开始执行,5s执行一次。new Timer().schedule(new TimerTask() { @Override public void run() { System.out.println("Timer is running"); } }, 2000,5000);
由于自带Timer有以下缺陷,所以使用场景较少:
- 可以让程序以某个频率执行,但无法实现在指定时间运行;
- 执行任务的线程只有一个,当某一任务执行时间过长影响其他定时任务的准确性;
- 没有持久化机制;
- Timers没有真正的管理计划;
-
Quartz实现
-
第一步:定义job基类
-
方式1——不继承基类
@Component public class MyJob1 { public void sayHello() { System.out.println("hello MyJob1..."); } } public class MyWork { public void sayHello() { System.out.println("hello MyWork...."); } }
-
-
方式2——继承QuartzJobBean
public class Myjob2 extends QuartzJobBean { HelloService helloService; public HelloService getHelloService() { return helloService; } public void setHelloService(HelloService helloService) { this.helloService = helloService; } @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { helloService.helloSe(); } }
-
第2步:提供JobDetail和配置作业类的触发器
JobDetail也有两种提供方式
-
方式1————使用 MethodInvokingJobDetailFactoryBean
@Configuration public class QuartzConfig { @Bean JobDetail methodInvokingJobDetailFactoryBean() { MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean(); bean.setTargetBeanName("myJob1");//设置目标Bean(就是Job Bean的名字) bean.setTargetMethod("sayHello");//设置目标方法名 return bean; } }
-
方式2————使用 JobDetailFactoryBean
@Configuration public class QuartzConfig { @Bean JobDetail jobDetailFactoryBean() { JobDetailFactoryBean bean = new JobDetailFactoryBean(); bean.setJobClass(MyJob2.class); JobDataMap map = new JobDataMap(); map.put("myWork", new MyWork()); bean.setJobDataMap(map); return bean; } }
触发器配置
Quartz的作业触发器有两种,分别是 org.springframework.scheduling.quartz.SimpleTriggerBean org.springframework.scheduling.quartz.CronTriggerBean-
方式1————使用 SimpleTriggerFactoryBean
@Bean SimpleTriggerFactoryBean simpleTriggerFactoryBean() { SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean(); bean.setStartTime(new Date()); bean.setRepeatCount(3); bean.setRepeatInterval(2000); bean.setJobDetail(methodInvokingJobDetailFactoryBean().getObject()); return bean; }
-
方式2————使用 CronTrigger
@Bean CronTrigger cronTriggerFactoryBean() { CronTriggerFactoryBean bean = new CronTriggerFactoryBean(); bean.setCronExpression("0/5 * * * * ?"); bean.setJobDetail(jobDetailFactoryBean().getObject()); return bean; }
配置SchedulerFactoryBean
@Bean SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean bean = new SchedulerFactoryBean(); bean.setTriggers(simpleTriggerFactoryBean().getObject(),cronTriggerFactoryBean().getObject()); return bean; }
-
-
第3步:开启测试
@SpringBootApplication @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
-
-
task——Spring3.0
-
第一步:定义基类
@Service public class HelloService { public String helloSe() { return "hello service"; } }
-
-
第2步:开启定时任务
@Component public class Myschedule { @Scheduled(fixedDelay = 2000) public void sch1() { System.out.println("fixedDelay执行"+new Date()); } @Scheduled(fixedRate = 2000) public void sch2() { System.out.println("fixedRate执行"+new Date()); } @Scheduled(initialDelay = 2000,fixedDelay = 2000) public void sch3() { System.out.println("initialDelay"+new Date()); } @Scheduled(cron ="" ) public void sch4() { System.out.println("initialDelay"+new Date()); } }
参数解释
- cron:指定cron表达式
- fixedDelay:An interval-based trigger where the interval is measured from the completion time of the previous task. The time unit value is measured in milliseconds.即表示从上一个任务完成开始到下一个任务开始的间隔,单位是毫秒。
- fixedRate:An interval-based trigger where the interval is measured from the start time of the previous task. The time unit value is measured in milliseconds.即从上一个任务开始到下一个任务开始的间隔,单位是毫秒。