quartz 定时任务

好久没更新了,因为感觉没什么可写的·····

这是基于spring boot的quartz 定时任务简单实现。

1、Controller代码

@Controller
@RequestMapping("/time")
public class TimeController {

    private final static String GROUPNAME = "MyJob";

    private static Long testId = new Long(1);

    @PostConstruct
    public void init() throws SchedulerException {
        System.out.println("logalert_init start");
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        addQuartzJob(testId, "localSystemName", "env", "0/5 * * * * ?");
        scheduler.start();
        System.out.println("logalert_init end");
    }

    private static void executeOneQuartzJob(Long id, String localSystemName, String env) {
        try {
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
            JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                    .withIdentity(id+"",GROUPNAME).usingJobData("id", id).build();
            SimpleTrigger simpleTrigger = (SimpleTrigger) TriggerBuilder.newTrigger()
                    .withIdentity(id+"",GROUPNAME).startAt(new Date()).build();
//            scheduler.addJob(jobDetail, true);
            scheduler.scheduleJob(jobDetail, simpleTrigger);
//            scheduler.start();
//            Thread.sleep(5000);
//
//            TriggerKey triggerKey = TriggerKey.triggerKey(localSystemName + "_" + env + "_" + id, GROUPNAME);
//
//            scheduler.pauseTrigger(triggerKey);// 停止触发器
//            scheduler.unscheduleJob(triggerKey);
//            JobKey jobKey = JobKey.jobKey(localSystemName + "_" + env + "_" + id, GROUPNAME);
//            scheduler.deleteJob(jobKey);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Scheduled(fixedRate = 5000)
    public void flush() throws SchedulerException {
        System.out.println("flush start");

        addQuartzJob(++testId, "localSystemName", "env", "0/5 * * * * ?");
        System.out.println("flush end:"+testId);
    }

    private static void addQuartzJob(Long id, String localSystemName, String env, String corntabEx) {
        try {
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
            JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                    .withIdentity(id+"",GROUPNAME).usingJobData("id", id).build();
            CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                    .withIdentity(id+"",GROUPNAME)
                    .withSchedule(CronScheduleBuilder.cronSchedule(corntabEx)).build();
            scheduler.scheduleJob(jobDetail, cronTrigger);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static void removeQuartzJob(Long id) {
        try {
            String jobName = id+"";
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, GROUPNAME);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            scheduler.pauseTrigger(triggerKey);// 停止触发器
            scheduler.unscheduleJob(triggerKey);
            JobKey jobKey = JobKey.jobKey(jobName, GROUPNAME);
            scheduler.deleteJob(jobKey);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

当 Scheduler 决定了是时候运行 Job 时,方法 execute() 就会被调用,并传递一个 JobExecutionContext 对象给这个 Job。

当 Scheduler 调用一个 Job,一个 JobexecutionContext 传递给 execute() 方法。JobExecutionContext 对象让 Job 能访问 Quartz 运行时候环境和 Job 本身的明细数据。
角色 SchedulerFactory 就是用来产生 Scheduler 实例的。当 Scheduler 实例被创建之后,就会存到一个仓库中(org.quartz.impl.SchedulerRepository),这个仓库还提供了通过一个 class loader 查询实例的机制。要使用 Scheduler 实例,客户端必须从工厂(和随同的仓库中)使用不同方法调用来获取到它们。

Trigger(触发器)的责任就是触发一个 Job 去执行。当用 Scheduler 注册一个 Job 的时候要创建一个 Trigger 与这个 Job 相关联。
SimpleTrigger 是两个之中简单的那个,它主要用来激发单事件的 Job,Trigger 在指定时间激发,并重复 n 次--两次激发时间之间的延时为 m,然后结束作业。
CronTrigger 非常复杂且强大。它是基于通用的公历,当需要用一种较复杂的时间表去执行一个 Job 时用到。
这两个触发器以上代码都已用到。

2、Job代码

public class MyJob implements Job {

//    @Autowired
//    private MyService myService;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        Long id = (Long) context.getMergedJobDataMap().get("id");
        System.out.println("MyJob id is "+id);
//        String back = myService.getFromService(id);
        MyService myService = SpringBeanFactory.getBean(MyService.class);
        String back = myService.getFromService(id);
        System.out.println("from Service:"+back);
    }
}

3、service的实现类

@Service
public class MyServiceImpl implements MyService {

    @Override
    public String getFromService(Long id){
        return "hello:"+id;
    }
}

4、启动类

注意一定要有@EnableScheduling注解否则会抛出异常,具体的异常忘了·······

@SpringBootApplication
@EnableScheduling
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}
}

5、如果你的项目使用了maven,那么恭喜你

		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz</artifactId>
			<version>2.2.1</version>
		</dependency>


6、我所遇到的坑:

@PostConstruct    使用这个注解的方法只会执行一次,在bean实例化之前执行,而我在这个方法里

做了这事:scheduler.start();

也就是启动定时任务,

而myJob里会调用myservice,如果使用@Autowired的方法获得myservice,就会抛出空值的问题。

所以需要使用getBean的方法获得bean实例。


最后贴上获取bean的代码:

@Component
public class SpringBeanFactory implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 获取某个Bean的对象
     */
    public static <T> T getBean(Class<T> clazz) {
        try {
            return applicationContext.getBean(clazz);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

刚刚接触,如有错误,还请各位大佬指出错误。

博客不定时更新·········






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值