Springboot+Quartz 实战

1、添加依赖
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.3.0</version>
        <exclusions>
            <exclusion>
                <artifactId>slf4j-api</artifactId>
                <groupId>org.slf4j</groupId>
            </exclusion>
        </exclusions>
        <!-- quartz 默认使用c3p0连接池,如果项目中使用的不是c3p0 则需要排除依赖包 -->
        <exclusions>
            <exclusion>
                <artifactId>c3p0</artifactId>
                <groupId>c3p0</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
    </dependency>
2、添加注解
    工程启动类:
        @SpringBootApplication
        @EnableScheduling //开启定时注解
        public class QuartzApplication {

            public static void main(String[] args) {
                SpringApplication.run(QuartzApplication.class, args);
            }
        }
3、添加配置
    配置类
        @Configuration
        public class QuartzConfigration {

            /**
             * 配置定时任务
             * @param task
             * @return
             */
            @Bean(name="sayHelloJodDetail")
            public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduleTaskImpl task){
                MethodInvokingJobDetailFactoryBean jodDetail = new MethodInvokingJobDetailFactoryBean();
                /**
                 * 是否并发执行
                 * 例如:每5秒执行一次任务,但是当前任务还没有执行完,就已经过了5秒了。
                 * 如果此处为true,则下一个任务执行;
                 * 如果此处为false,则下一个任务会等待上一个任务执行完后再执行
                 */
                jodDetail.setConcurrent(true);
                /*
                 * 为需要执行的实体类对象的对象
                 */
                jodDetail.setTargetObject(task);
                /*
                 * sayHello 为需要执行的方法
                 * 通过这几个配置,告诉JodDetailFactoryBean 我们需要定时执行scheduleTask 类中的sayHello 方法
                 */
                jodDetail.setTargetMethod("sayHello");
                return jodDetail;
            }
            /**
             * 配置定时任务的触发器,也就是什么时候出发执行定时任务
             * @param jodDetail
             * @return
             */
            @Bean(name="sayHelloJodTrigger")
            public CronTriggerFactoryBean cronJodTrigger(JobDetail sayHelloJodDetail){
                CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
                trigger.setJobDetail(sayHelloJodDetail);
                /*
                 * 初始时的cron 表达式 (每秒执行一次)
                 */
                trigger.setCronExpression("*/1 * * * * ?");
                /*
                 * 设置trigger 的分组和名称
                 */
                trigger.setGroup("payMentGroup");
                trigger.setName("payMent"); 
                return trigger;
            }
            /**
             * 配置定时任务
             * @param task
             * @return
             */
            @Bean(name="sayHello2JodDetail")
            public MethodInvokingJobDetailFactoryBean detailFactoryBean2(ScheduleTaskImpl task){
                MethodInvokingJobDetailFactoryBean jodDetail = new MethodInvokingJobDetailFactoryBean();
                /**
                 * 是否并发执行
                 * 例如:每5秒执行一次任务,但是当前任务还没有执行完,就已经过了5秒了。
                 * 如果此处为true,则下一个任务执行;
                 * 如果此处为false,则下一个任务会等待上一个任务执行完后再执行
                 */
                jodDetail.setConcurrent(false);
                /*
                 * 为需要执行的实体类对象的对象
                 */
                jodDetail.setTargetObject(task);
                /*
                 * sayHello 为需要执行的方法
                 * 通过这几个配置,告诉JodDetailFactoryBean 我们需要定时执行scheduleTask 类中的sayHello 方法
                 */
                jodDetail.setTargetMethod("sayHello2");
                return jodDetail;
            }
            /**
             * 配置定时任务的触发器,也就是什么时候出发执行定时任务
             * @param jodDetail
             * @return
             */
            @Bean(name="sayHello2JodTrigger")
            public CronTriggerFactoryBean cronJodTrigger2(JobDetail sayHello2JodDetail){
                CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
                trigger.setJobDetail(sayHello2JodDetail);
                /*
                 *初始时的cron 表达式 (每秒执行一次)
                 */
                trigger.setCronExpression("*/5 * * * * ?");
                /*
                 * 设置trigger 的分组和名称
                 */
                trigger.setGroup("payMentGroup");
                trigger.setName("payMent2");
                return trigger;
            }
            /**
             * 定义quartz 调度工厂
             * @param cronJodTrigger
             * @return
             */
            @Bean(name="sheduler")
            public SchedulerFactoryBean shedulerFactory(Trigger  ...trigger){
                
                Properties pro = new Properties();
                // 配置实例
                pro.put("org.quartz.scheduler.instanceId", "AUTO");
                // 配置线程池
                pro.put("org.quartz.threadPool.threadCount", "5");
                /*备注:如果使用数据库来实现quartz分布式部署,则需要添加相关配置 

                SchedulerFactoryBean bean = new SchedulerFactoryBean();
                bean.setQuartzProperties(pro);
                /*
                 * 用于quartz 集群,QuartzSchedule 启动时更新已存在的jod
                 */
                bean.setOverwriteExistingJobs(true);
                /*
                 * 延时启动,应用启动1秒后
                 */ 
                bean.setStartupDelay(1);
                /*
                 * 注册触发器
                 */
                bean.setTriggers(trigger);
                return bean;
            }
            
        }
4、任务使用
    控制层
        @Component
        @Path("/")
        public class QuartzRest {
            
            private Logger log = LoggerFactory.getLogger(QuartzRest.class);

            @Autowired
            RedisService redisService;
            
            @Autowired
            ScheduleTask scheduleTask;

            /**
             * 操作定时任务
             * @param json
             * @return
             * @throws Exception
             */
            @POST
            @Path("/operationCronTrigger")
            @Consumes({ MediaType.APPLICATION_JSON })
            @Produces({ MediaType.APPLICATION_JSON })
            public String operationCronTrigger(String json) throws Exception{
                JSONObject jsonObject = null;
                try {
                    jsonObject = JSON.parseObject(json);
                } catch (Exception e) {
                    throw new NetcoreException("PARAMS_ERROR","传入参数有误,请以json格式字符串传入。传入参数 =: "+json);
                }
                String result = null;
                //根据操作类型执行
                switch (jsonObject.getString("operationType")) {
                case "pause": // 暂定定时任务
                    result = pauseCronTrigger(json);
                    break;
                case "update": // 修改定时任务
                    result = updateCronTriggerByGroup(json);
                    break;
                case "resume": // 重启定时任务
                    result = resumeCronTrigger(json);
                    break;
                case "delete": // 删除定时任务
                    result = deleteCronTrigger(json);
                    break;
                default:
                    Map<String, String> map = new HashMap<>();
                    map.put("code", "200");
                    map.put("msg", "操作类型不正确【pause:暂定,update:修改,resume:重启,delete:删除】");
                    result = JSON.toJSONString(map);
                    break;
                }
                return result;
            }
            /**
             * 暂定定时任务
             * @param json
             * @return
             * @throws Exception
             */
            private String pauseCronTrigger(String json) throws Exception{
                Map<String, Object> jsonMap = JSON.parseObject(json);
                Map<String, String> map = new HashMap<>();
                scheduleTask.pauseCronTrigger((String)jsonMap.get("payMent"),(String)jsonMap.get("payMentGroup"));
                map.put("code", "SUCCESS");
                return JSON.toJSONString(map);
            }
            /**
             * 修改定时任务
             * @param json
             * @return
             * @throws Exception
             */
            private String updateCronTriggerByGroup(String json) throws Exception{
                JSONObject jsonObj = JSON.parseObject(json);
                Map<String, Object> map = new HashMap<>();
                map = scheduleTask.updateCronTrigger(jsonObj.getString("jodTrigger"),jsonObj.getString("payMent"),jsonObj.getString("payMentGroup"),jsonObj.getString("cronExpression"));
                return JSON.toJSONString(map);
            }
            /**
             * 重启定时任务
             * @param json
             * @return
             * @throws Exception
             */
            private String resumeCronTrigger(String json) throws Exception{
                Map<String, Object> jsonMap = JSON.parseObject(json);
                Map<String, Object> map = new HashMap<>();
                boolean ok = scheduleTask.resumeTrigger((String)jsonMap.get("payMent"),(String)jsonMap.get("payMentGroup"));
                if (ok) {
                    map.put("msg","启动成功");
                }else{
                    map.put("msg","启动失败");
                }
                return JSON.toJSONString(map);
            }
            /**
             * 删除定时任务
             * @param json
             * @return
             * @throws Exception
             */
            private String deleteCronTrigger(String json) throws Exception{
                Map<String, Object> jsonMap = JSON.parseObject(json);
                Map<String, Object> map = new HashMap<>();
                boolean ok = scheduleTask.deleteCronTrigger((String)jsonMap.get("payMent"),(String)jsonMap.get("payMentGroup"));
                if (ok) {
                    map.put("msg","删除成功");
                }else{
                    map.put("msg","删除失败");
                }
                return JSON.toJSONString(map);
            }
            
        }
    接口:
        public interface ScheduleTask {

            public void sayHello();

            public void pauseCronTrigger(String jodName, String jodGroup);

            public boolean deleteCronTrigger(String jodName, String jodGroup);

            public boolean resumeTrigger(String jodName, String jodGroup);

            public Map<String, Object> updateCronTrigger(String jodTrigger,String jodName, String jodGroup, String cronExpression)
                    throws SchedulerException;

            void sayHello2();

         public boolean trigger(String jodName, String jodGroup) throws SchedulerException;

        }
        
    实现类:
        @Component    //此注解必加
        public class ScheduleTaskImpl implements ScheduleTask {

            private static Logger log = LoggerFactory.getLogger(ScheduleTaskImpl.class);
            
            @Resource(name="sayHelloJodDetail")
            private JobDetail sayHelloJodDetail;
            
            @Resource(name="sayHelloJodTrigger")
            private CronTrigger sayHelloJodTrigger;
            
            @Resource(name="sayHello2JodDetail")
            private JobDetail sayHello2jodDetail;
            
            @Resource(name="sayHello2JodTrigger")
            private CronTrigger sayHello2JodTrigger;
            
            @Resource(name="sheduler")
            private Scheduler scheduler;
            
            @Autowired
            SPolicymainMapper sPolicyMainMapper;
            
            @Override
            public void sayHello() {
                log.info("定时任务正常执行:{}",new Date());
                SPolicymain sPolicyMain  = sPolicyMainMapper.selectByRequestId("201801223495367").get(0);
                log.info("sayHello() 交易流水号[{}]重复提交,保单号[{}]", sPolicyMain, sPolicyMain.getPolicyNo());
            }
            @Override
            public void sayHello2() {
                log.info("定时任务正常执行:{}",new Date());
                SPolicymain sPolicyMain  = sPolicyMainMapper.selectByRequestId("201801223495367").get(0);
                log.info("sayHello2() 交易流水号[{}]重复提交,保单号[{}]", sPolicyMain, sPolicyMain.getPolicyNo());
            }
            @Override
            public Map<String,Object> updateCronTrigger(String jodTrigger,String jodName,String jodGroup,String cronExpression) throws SchedulerException{
                Map<String,Object> map = new HashMap<>();
                if (!checkExists(jodName, jodGroup)) {
                    map.put("code", 500);
                    map.put("msg", "定时任务不存在!");
                    return map;
                }
                TriggerKey triggerKey = TriggerKey.triggerKey(jodName, jodGroup);
                CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
                // 当前trigger 使用的表达式
                String currentCron = trigger.getCronExpression();
                // 传入的表达式
                String searchCron = cronExpression;
                if (currentCron.equals(searchCron)) {
                    //相同则不刷新
                    log.info("定时表达式未曾改变:[进行中的:{}、获取的:{}",currentCron,searchCron);
                }else{
                    //表达调度构建器
                    CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(searchCron);
                    //按新的 cronExpression 表达式 重新构建trigger
                    trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
                    trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                            .withSchedule(scheduleBuilder).build();
                    // 如果Trigger  还活着  需要先停掉 才能执行重新设置操作
                    if (checkExists(jodName,jodGroup)) {
                        scheduler.pauseTrigger(triggerKey);
                    }
                    // 按新的trigger 重新设置jod执行
                    if ("sayHelloJodTrigger".equals(jodTrigger)) {
                        scheduler.rescheduleJob(sayHelloJodTrigger.getKey(), trigger);
                    }
                    if ("sayHello2JodTrigger".equals(jodTrigger)) {
                        scheduler.rescheduleJob(sayHello2JodTrigger.getKey(), trigger);
                    }
                    currentCron = searchCron;
                }
                resumeTrigger(jodName,jodGroup);
                map.put("code", 200);
                map.put("msg", "定时表达式设置成功!");
                return map;
            }
            /**
             * 开始定时任务
             * @param jodName
             * @param jodGroup
             * @throws SchedulerException
             */
            @Override
            public boolean resumeTrigger(String jodName,String jodGroup){
                TriggerKey triggerKey = TriggerKey.triggerKey(jodName, jodGroup);
                boolean ok = false;
                try {
                    if (checkExists(jodName,jodGroup)) {
                        scheduler.resumeTrigger(triggerKey);
                        log.info("pause jod success, triggerKey:{}, jodGroup:{}, jodName:{}",triggerKey,jodGroup,jodName);
                    }
                    ok = scheduler.isStarted();
                } catch (SchedulerException e) {
                    e.printStackTrace();
                }
                return ok;
            }
            /**
             * 暂定定时任务
             * @param jodName
             * @param jodGroup
             * @throws SchedulerException
             */
            @Override
            public void pauseCronTrigger(String jodName,String jodGroup){
                TriggerKey triggerKey = TriggerKey.triggerKey(jodName, jodGroup);
                try {
                    if (checkExists(jodName,jodGroup)) {
                        scheduler.pauseTrigger(triggerKey);
                        log.info("pause jod success, triggerKey:{}, jodGroup:{}, jodName:{}",triggerKey,jodGroup,jodName);
                    }
                } catch (SchedulerException e) {
                    e.printStackTrace();
                }
            }
            /**
             * 删除定时任务
             * @param jodName
             * @param jodGroup
             * @throws SchedulerException
             */
            @Override
            public boolean deleteCronTrigger(String jodName,String jodGroup){
                TriggerKey triggerKey = TriggerKey.triggerKey(jodName, jodGroup);
                boolean ok = false;
                try {
                    if (checkExists(jodName,jodGroup)) {
                        scheduler.pauseTrigger(triggerKey);
                        ok = scheduler.unscheduleJob(triggerKey);
                        log.info("pause jod success, triggerKey:{}, jodGroup:{}, jodName:{}",triggerKey,jodGroup,jodName);
                    }
                } catch (SchedulerException e) {
                    e.printStackTrace();
                }
                return ok;
            }

            private boolean checkExists(String jodName, String jodGroup) throws SchedulerException {
                TriggerKey triggerKey = TriggerKey.triggerKey(jodName, jodGroup);
                return scheduler.checkExists(triggerKey);
            }
            /**
             * 立即执行函数
             * 只执行一次 并且不会改变任务状态 
             * @param jodName
             * @param jodGroup
             * @throws SchedulerException
             */
            @Override
            public boolean trigger(String jodName, String jodGroup) throws SchedulerException {
                boolean ok = false;
                try {
                    JobKey key = new JobKey(jodName, jodGroup);
                    scheduler.triggerJob(key);
                    ok = true;
                } catch (Exception e) {
                }
                return ok;
            }
        }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值