spring boot + spring batch+ quartz实例

注:本文非基础教学类文章

首先工程用到的主要jar包

spring-batch-core-3.0.0.jar

quartz-2.1.6.jar


(一) quartz实现  实际开发过程中系统中肯定有任务管理模块,所以就按实际开发来写了
import com.alibaba.fastjson.TypeReference;
import org.apache.commons.lang.StringUtils;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 定时job操作service
 *
 * @author
 * @create 2017年4月10日
 */
//@Service(version = "2.0",group = "",timeout = 3000000)
@Transactional
@SuppressWarnings("rawtypes")
public class JobService {


    @Autowired
    private QrtzTriggersMapper qrtzTriggersMapper;//任务DAO

    @Autowired
    private Scheduler scheduler;//定时器

    /**
     * 初始化执行调度任务
     */
    @PostConstruct
    public void initScheduler() {
        try {
            scheduler.start();
        } catch (SchedulerException e) {
            log.error("初始化调度任务失败:", e);
        }
    }



    /**
     * 获取job列表
     *
     * @param page
     * @return
     */
    @Override
    public String loadSchedulers(Map<String,Object> map) {
        Page<QrtzJobDetails> page = new Page<>(Integer.parseInt(map.get("row").toString()),
                Integer.parseInt(map.get("page").toString()));
        map.put("offset",page.getOffset());
        map.put("pageSize",page.getPageSize());
        List<QrtzJobDetails> list = schedulerJobMapper.loadSchedulers(map);
        int count = schedulerJobMapper.loadSchedulerCount(map);
        return JsonUtil.toJSONString(page.hold(list, count));
    }
 

    /**
     * 解析jobDetail参数
     *
     * @param qrtzJobDetails
     * @return
     */
    // 将参数放入map
    @SuppressWarnings("unchecked")
    public Map getJobParams(QrtzJobDetails qrtzJobDetails) {
        String classNamePath = null;
        if (StringUtils.isEmpty(qrtzJobDetails.getJobClassPath())) {
            classNamePath = "com.gomefinance.ecms.web.timer";// 任务类路径 没有选择的默认到该路径
        } else {
            classNamePath = qrtzJobDetails.getJobClassPath();
        }
        qrtzJobDetails.setJobClassName(classNamePath + "." + qrtzJobDetails.getJobClassName());
        Map parameterMap = new HashMap();
        String spitParamKey = "";
        String spitParamValue = "";
        String getParams[] = qrtzJobDetails.getParameterJson().replaceAll("\r|\n", "").split(";");
        if (qrtzJobDetails.getParameterJson().length() > 0) {
            for (String getParam : getParams) {
                spitParamKey = getParam;
                spitParamValue = getParam;
                int idx = spitParamKey.indexOf(",");
                spitParamKey = spitParamKey.substring(0, idx);
                int idx1 = spitParamValue.indexOf(",");
                spitParamValue = spitParamValue.substring(idx1 + 1, spitParamValue.length());
                parameterMap.put(spitParamKey.trim(), spitParamValue.trim());
            }
        }
        return parameterMap;
    }


    /**
     * 新增计划
     *
     * @param param
     * @return
     */
    public String addControlTrigger(String param) {
        QrtzTriggers qrtzqTriggers = JsonUtil.toAny(param,new TypeReference<QrtzTriggers>(){});
        //验证时间间隔不能为空
        if (",,,,,".equals(qrtzqTriggers.getTimeIntreval())) {
            return JsonUtil.toJSONString(new EntityWrapperResponse(EnumSystem.FAIL, "执行计划的方式不能为空,请核对!"));
        }
        //查询数据库中 任务类名称不能和计划相同
        QrtzJobDetails qrtzJobDetails = schedulerJobMapper.loadSchedulerByName(qrtzqTriggers.getTriggerName());
        if (qrtzJobDetails != null) {
            return JsonUtil.toJSONString(new EntityWrapperResponse(EnumSystem.FAIL, "计划名称不能与任务名称相同,请核对!"));
        }
        //一个任务相同计划执行时间只能添加一次!TODO

        //计划名称不能重复
        QrtzTriggersKey qrtzTriggersKey = new QrtzTriggersKey(qrtzqTriggers.getSchedName(),
                qrtzqTriggers.getTriggerName(), qrtzqTriggers.getTriggerGroup());
        QrtzTriggers qrtz = qrtzTriggersMapper.selectByPrimaryKey(qrtzTriggersKey);
        if (qrtz != null) {
            return JsonUtil.toJSONString(new EntityWrapperResponse(EnumSystem.FAIL, qrtzqTriggers.getTriggerName() + ",计划名称已经存在,请核对!"));
        }
        //新增计划
        this.addTrigger(qrtzqTriggers);
        return JsonUtil.toJSONString(new EntityWrapperResponse(EnumSystem.OK));
    }

    /**
     * 根据JObName获取job
     * @param jobName
     * @return
     */
    @Override
    public QrtzJobDetails loadSchedulerByJobName(String jobName) {
        return schedulerJobMapper.loadSchedulerByName(jobName);
    }

    /**
     * 根据jobName获取计划列表
     * @param map
     * @return
     */
    @Override
    public String loadTrigger(Map<String,Object> map) {
        Page<QrtzTriggers> page = new Page<>(Integer.parseInt(map.get("row").toString()),
                Integer.parseInt(map.get("page").toString()));
        map.put("offset",page.getOffset());
        map.put("pageSize",page.getPageSize());
        List<QrtzTriggers> list = qrtzTriggersMapper.selectByJobName(page.getOffset(),page.getPageSize(),String.valueOf(map.get("jobName")));
        int count = qrtzTriggersMapper.selectCountByJobName(String.valueOf(map.get("jobName")));
        return JsonUtil.toJSONString(page.hold(list,count));
    }

    @SuppressWarnings("unchecked")
    public void addTrigger(QrtzTriggers qrtzqTriggers) {
        try {
            if (this.scheduler == null) {
                return;
            }
            String schedJobGroup = qrtzqTriggers.getJobGroup();//任务分组,后期维护到数据字典中。
            String schedTriggerGroup = qrtzqTriggers.getTriggerName();//触发器分组,后期维护到数据字典中。
            JobKey jobKey = new JobKey(qrtzqTriggers.getJobName(), schedJobGroup);
            TriggerBuilder tb = TriggerBuilder.newTrigger();
            tb.withIdentity(qrtzqTriggers.getTriggerName(), schedTriggerGroup);

            // 构建triggerBuilder
            setTrigBuilder(qrtzqTriggers, tb);
            tb.forJob(jobKey);
            Trigger trig = tb.build();
            this.scheduler.start();
            this.scheduler.scheduleJob(trig);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("后台有错,错误【:" + e.getMessage() + "】,请检查!");
        }

    }

    /***
     * 设置触发器触发时间*
     *
     * @param qrtzqTriggers
     * @param tb
     * @throws ParseException
     */
    private void setTrigBuilder(QrtzTriggers qrtzqTriggers, TriggerBuilder<Trigger> tb) throws ParseException {
        int type = Integer.parseInt(qrtzqTriggers.getTriggerType());
        String value[] = qrtzqTriggers.getTimeIntreval().split(",");
        switch (type) {
            case 1:
                //执行一次次
                excuteOnce(tb, value);
                break;
            case 2:
                //每天某分钟执行
                everyDayMinute(tb, value);
                //this.addTrigger(qrtzqTriggers,Integer.parseInt(value[1]));
                break;
            case 3:
                //每天某小时某分执行
                everyDayHourMinue(tb, value);
                break;
            case 4:
                //某周某小时某分执行
                everyWeekHM(tb, value);
                break;
            case 5:
                everyDayHM(tb, value);
                break;
            case 6: {
                //cron表达式
                char[] chars = qrtzqTriggers.getTimeIntreval().toCharArray();
                String expression = "";
                int k = 0;
                for (int i = 0; i < chars.length; i++) {
                    if (k >= 5) {
                        expression += chars[i];
                    }
                    if (chars[i] == ',') {
                        k++;
                    }
                }
                try {
                    cronScheduler(tb, expression);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new BusinessException("cron表达式验证错误。");
                }
            }
        }
    }

    /***
     * 执行一次*
     * @param tb
     * @param value
     */
    private void excuteOnce(TriggerBuilder<Trigger> tb, String[] value) {
        Date date = DateUtils.convertString(value[0]);
        tb.startAt(date);
        tb.withDescription("执行一次,执行时间:" + DateUtils.getFormatedDate(date, "yyyy-MM-dd HH:mm:ss"));
    }

    /***
     * 每天某分钟执行*
     * @param tb
     * @param value
     */
    @SuppressWarnings("unchecked")
    private void everyDayMinute(TriggerBuilder<Trigger> tb, String[] value) {
        int minute = Integer.parseInt(value[1]);
        ScheduleBuilder sb = CalendarIntervalScheduleBuilder.calendarIntervalSchedule().withIntervalInMinutes(minute);

        tb.startNow();
        tb.withSchedule(sb);
        tb.withDescription("每:" + minute + "分钟执行!");
    }

    /***
     * 每天某小时某分执行 *
     * @param tb
     * @param value
     */
    @SuppressWarnings({"unchecked"})
    private void everyWeekHM(TriggerBuilder<Trigger> tb, String[] value) throws BusinessException {
        StringBuffer aryBuString = new StringBuffer();
        @SuppressWarnings("unused")
        String week = getValues(value, aryBuString);
        //获得周
        String getweek = getWeek(aryBuString);
        //获得小时
        String gethour = getHour(aryBuString);
        String[] aryTime1 = gethour.split(":");
        String h1 = aryTime1[0];
        String m1 = aryTime1[1];
        String cronExperssion = "0 " + m1 + " " + h1 + " ? * " + getweek;
        ScheduleBuilder sb4 = null;
        try {
            sb4 = CronScheduleBuilder.cronSchedule(cronExperssion);
        } catch (Exception e) {
            log.error("CronScheduleBuilder.cronSchedule error", e);
            throw new BusinessException(e.getMessage());
        }
        tb.startNow();
        tb.withSchedule(sb4);
        StringBuffer weekName = new StringBuffer();
        for (int i = 0; i < getweek.split(",").length; i++) {
            weekName.append(DateUtils.getWeek(Integer.parseInt(getweek.split(",")[i])) + ",");
        }
        String getWeekName = weekName.substring(0, weekName.length() - 1).toString();
        tb.withDescription("每周:" + getWeekName + "," + h1 + ":" + m1 + "执行!");
    }

    /***
     * 获得传入参数*
     *
     * @param value
     * @param aryBuString
     * @return
     */
    private String getValues(String[] value, StringBuffer aryBuString) {
        String week = "";
        int aryLength = value.length;
        for (int i = 0; i < aryLength; i++) {
            week = value[i].toString();
            if (!week.isEmpty()) {
                aryBuString.append(value[i] + ",").toString();
            }
        }
        return week;
    }

    /***
     * 获得周*
     *
     * @param aryBuString
     * @return
     */
    private String getWeek(StringBuffer aryBuString) {
        String getweek = aryBuString.toString();
        getweek = getweek.substring(0, getweek.length() - 1);
        int idx = getweek.lastIndexOf(",");
        getweek = getweek.substring(0, idx);
        return getweek;
    }

    /***
     * 获得天*
     *
     * @param aryBuString
     * @return
     */
    private String getDays(StringBuffer aryBuString) {
        String getDays = aryBuString.toString();
        getDays = getDays.substring(0, getDays.length() - 1);
        int idx = getDays.lastIndexOf(",");
        getDays = getDays.substring(0, idx);
        return getDays;
    }

    /***
     * 获得小时*
     *
     * @param aryBuString
     * @return
     */
    private String getHour(StringBuffer aryBuString) {
        String gethour = aryBuString.toString();
        gethour = gethour.substring(0, gethour.length() - 1);
        int idx1 = gethour.lastIndexOf(",");
        gethour = gethour.substring(idx1 + 1, gethour.length());
        return gethour;
    }

    /***
     * 每天某小时某分执行*
     *
     * @param tb
     * @param value
     */
    @SuppressWarnings("unchecked")
    private void everyDayHourMinue(TriggerBuilder<Trigger> tb, String[] value) {
        String[] aryTime = value[2].split(":");
        int hour = Integer.parseInt(aryTime[0]);
        int m = Integer.parseInt(aryTime[1]);
        ScheduleBuilder sb1 = CronScheduleBuilder.dailyAtHourAndMinute(hour, m);
        tb.startNow();
        tb.withSchedule(sb1);
        tb.withDescription("每天:" + hour + ":" + m + "执行!");
    }

    @SuppressWarnings({"unchecked"})
    private void everyDayHM(TriggerBuilder<Trigger> tb, String[] value) {
        StringBuffer aryBuString = new StringBuffer();
        @SuppressWarnings("unused")
        String week = getValues(value, aryBuString);
        //获得天
        String getday = getDays(aryBuString);
        //获得小时
        String gethour = getHour(aryBuString);
        String[] aryTime2 = gethour.split(":");
        String h2 = aryTime2[0];
        String m2 = aryTime2[1];
        String cronExperssion1 = "0 " + m2 + " " + h2 + " " + getday + " * ?";
        ScheduleBuilder sb5 = null;
        try {
            sb5 = CronScheduleBuilder.cronSchedule(cronExperssion1);
        } catch (Exception e) {
            log.error("CronScheduleBuilder.cronSchedule error", e);
        }
        tb.startNow();
        tb.withSchedule(sb5);
        String dayName = DateUtils.getDay(getday);
        tb.withDescription("每月:" + dayName + "," + h2 + ":" + m2 + "执行!");
    }


    /***
     * cron表达式*
     *
     * @param tb
     * @param expression
     */
    @SuppressWarnings({"unchecked"})
    private void cronScheduler(TriggerBuilder<Trigger> tb, String expression) {
        ScheduleBuilder sb6 = null;
        try {
            sb6 = CronScheduleBuilder.cronSchedule(expression);
        } catch (Exception e) {
            e.printStackTrace();
        }
        tb.startNow();
        tb.withSchedule(sb6);
        tb.withDescription("CronTrigger表达式:" + expression);
    }

}

(二)实际的jod

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.stereotype.Component;

@Component
public class TestTimer extends QuartzScheduleBaseTimer {

    private static final Logger logger = LoggerFactory.getLogger(AccountExportTimer.class);

    @Override
    public JobExecution doJob(JobDataMap dataMap, JobExecutionContext context)
            throws Exception {
       //实现

    }
    public CommonService getCommonService(){
        return (CommonService)SpringContextHolder.getBean("commonService");
    }
    public Job getAccountExportJob(){
        return (Job)SpringContextHolder.getBean("exportJob");
    }
}

(三)spring batch


import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.listener.JobExecutionListenerSupport;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SimpleAsyncTaskExecutor;

/**
* @ClassName:AccountExportJob
* @author:
* @Description:
* @date:2017年7月24日 下午4:46:23
 */
@Configuration
@EnableBatchProcessing
@EnableAutoConfiguration
public class TestJob {
    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    private JobStepListener listener;

    @Autowired
    private JobListener jobListener;

    /**
     * 读数据
     *
     * @return
     */
    @SuppressWarnings("rawtypes")
    @Bean
    public ItemReader testReader() {
        return new testReader();
    }


    // 3.写数据
    @SuppressWarnings("rawtypes")
    @Bean
    public ItemWriter testWriter() {
        return new testWriter();
    }

    @Bean
    public Job exportJob(JobBuilderFactory jobs, @Qualifier("testStep") Step testStep) {
        return jobs.get("testJob")
                .incrementer(new RunIdIncrementer())
                .listener(jobListener)
                .flow(accountExportStep)
                .end()
                .build();
    }
    @SuppressWarnings("unchecked")
    @Bean
    public Step testStep(StepBuilderFactory stepBuilderFactory) {
        return stepBuilderFactory.get("testStep")
                .listener(listener)
                .chunk(200)
                .reader(testReader())
                .writer(testWriter())
                .faultTolerant()
                .taskExecutor(new SimpleAsyncTaskExecutor())//设置并发方式执行
                .throttleLimit(10)//并发任务数为 10,默认为4
                .build();
    }
    @Bean
    public JobExecutionListener listener() {
        return new JobExecutionListenerSupport();
    }

}

*********************************reader***************************************8

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
@Component
public class TestReader extends MyBatisPagingItemReader<AccountEntry> implements
        StepExecutionListener {

    private static final Logger logger = LoggerFactory.getLogger(AccountExportReader.class);

    private StepExecution stepExecution;

    @Autowired
    private AccountEntryDataMapper accountEntryDataMapper;


    public AccountExportReader() {
        super();
        super.setQueryId("1000");
        setPageSize(10000);
    }

    @Autowired
    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        super.setSqlSessionFactory(sqlSessionFactory);
    }
    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void beforeStep(StepExecution stepExecution) {
        this.stepExecution = stepExecution;

    }
    @Override
    protected void doReadPage() {

    }
}

******************************************writer***********************************

import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;



/**
* @ClassName:AccountExportWriter
* @author:
* @Description:
* @date:2017年7月24日 下午3:45:49
 */
public class TestWriter implements ItemWriter, StepExecutionListener {

    private StepExecution stepExecution;
    @Autowired
    private AccountExportMapper accountExportMapper;

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void beforeStep(StepExecution stepExecution) {
        this.stepExecution = stepExecution;

    }
}




  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值