003-spring结合java类调用quartz

一、利弊

  针对001 中设置,不方便程序中动态添加任务,只能使用配置进行配置任务,

    适用于已知固定时刻需要执行的任务。

  针对002中设置,不方便结合调用spring注入的实体

    使用于程序内部新增添的任务

二、结合spring以及动态添加任务

  1.编写ApplicationContext对象注入类

@Component
public class SpringContextUtil implements ApplicationContextAware {
    // Spring应用上下文环境
    private static ApplicationContext applicationContext;

    /**
     * 实现ApplicationContextAware接口的回调方法。设置上下文环境
     *
     * @param applicationContext
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringContextUtil.applicationContext = applicationContext;
    }

    /**
     * @return ApplicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) {
        checkApplicationContext();
        if (applicationContext.containsBean(name)) {
            return (T) applicationContext.getBean(name);
        }
        return null;
    }

    /**
     * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(Class<T> clazz) {
        checkApplicationContext();
        return (T) applicationContext.getBean(clazz);
    }

    private static void checkApplicationContext() {
        if (applicationContext == null){
            throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextUtil");
        }
    }

    /**
     * 同步方法注册bean到ApplicationContext中
     *
     * @param beanName
     * @param clazz
     * @param original bean的属性值
     */
    public static synchronized void setBean(String beanName, Class<?> clazz,Map<String,Object> original) {
        checkApplicationContext();
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
        if(beanFactory.containsBean(beanName)){
            return;
        }
        //BeanDefinition beanDefinition = new RootBeanDefinition(clazz);
        GenericBeanDefinition definition = new GenericBeanDefinition();
        //类class
        definition.setBeanClass(clazz);
        //属性赋值
        definition.setPropertyValues(new MutablePropertyValues(original));
        //注册到spring上下文
        beanFactory.registerBeanDefinition(beanName, definition);
    }

    /**
     * 删除spring中管理的bean
     * @param beanName
     */
    public static void removeBean(String beanName){
        ApplicationContext ctx = SpringContextUtil.getApplicationContext();
        DefaultListableBeanFactory acf = (DefaultListableBeanFactory) ctx.getAutowireCapableBeanFactory();
        if(acf.containsBean(beanName)) {
            acf.removeBeanDefinition(beanName);
        }
    }

    /**
     * 根据bean的id来查找对象
     *
     * @param id
     * @return
     */

    public static <T> T getBeanById(String id) {
        return (T) applicationContext.getBean(id);
    }
}
View Code

  2.spring,xml配置

<bean id="spring" class="com.trace.common.quartz.SpringContextUtil" />

  3.编写Job接口工厂

public class JobFactory extends AdaptableJobFactory {

    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        //调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        //进行注入
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}

  4.注入Job工厂,以及quartz调度工厂

    <bean id="jobFactory" class="com.jd.ofc.trace.common.quartz.JobFactory"></bean>
    <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="jobFactory" ref="jobFactory"></property>
    </bean>

  5.java帮助类

public class TaskJobUtil {
    private static final Logger logger = LoggerFactory.getLogger(TaskJobUtil.class);

    private TaskJobUtil() {
    }

    /**
     * 添加任务
     *
     * @param job            要调用的job类
     * @param jobName        job名称
     * @param cronExpression 任务触发时间表达式
     * @param param          需要用到的参数,可在job类中的context获得
     */
    public static void addJob(Job job, String jobName, String cronExpression, Map param) {
        Scheduler scheduler = null;
        try {
            removeJob(jobName, job.getClass().getCanonicalName() + "Group");//删除原任务
            scheduler= (StdScheduler)SpringContextUtil.getBean("schedulerFactoryBean");
            JobDetail jobDetail = getJobDetail(job, jobName, param);
            String jobGroup = jobDetail.getGroup();
            CronTrigger cronTrigger = getCronTrigger(job, jobName, jobGroup, cronExpression);
            scheduler.scheduleJob(jobDetail, cronTrigger);
            logger.info("添加任务:" + jobName);
            startScheduler();
        } catch (SchedulerException e) {
            logger.error("", e);
        }
    }

    /**
     * 对外停止任务调度器方法
     */
    public static void stopJob() {
        shutdownScheduler();
    }

    /**
     * 启动调度器
     */
    protected static void startScheduler() {
        Scheduler scheduler = null;
        try {
            scheduler= (StdScheduler)SpringContextUtil.getBean("schedulerFactoryBean");
            //如果调度器未启动,启动调度器
            if (scheduler != null && !scheduler.isStarted()) {
                scheduler.start();
            }
        } catch (SchedulerException e) {
            logger.error("", e);
        }
    }

    /**
     * 关闭调度器,关闭后任务也都清除
     */
    protected static void shutdownScheduler() {
        Scheduler scheduler = null;
        try {
            scheduler= (StdScheduler)SpringContextUtil.getBean("schedulerFactoryBean");
            //如果调度器未关闭,关闭调度器
            if (scheduler != null && !scheduler.isShutdown()) {
                scheduler.shutdown();
            }
        } catch (SchedulerException e) {
            logger.error("", e);
        }
    }

    /**
     * 获取JobDetail
     *
     * @param job
     * @param param
     * @return
     */
    protected static JobDetail getJobDetail(Job job, String jobName, Map param) {
        Class jobClazz = job.getClass();
        if (jobName == null || "".equals(jobName)) {
            jobName = jobClazz.getCanonicalName();
        }
        String jobGroup = jobClazz.getCanonicalName() + "Group";

        JobDetail jobDetail = new JobDetail();
        jobDetail.setDurability(true);
        jobDetail.setRequestsRecovery(true);
        jobDetail.setName(jobName);
        jobDetail.setGroup(jobGroup);
        jobDetail.setJobClass(jobClazz);

        if (param != null && param.size() > 0) {
            JobDataMap jobDataMap = new JobDataMap(param);//存放参数
            jobDetail.setJobDataMap(jobDataMap);

            logger.info("任务 " + jobName + " jobDetail存放的参数:" + param);
        }
        return jobDetail;
    }

    /**
     * 获取触发器
     *
     * @param job
     * @param jobName
     * @param cronExpression
     * @return
     */
    protected static CronTrigger getCronTrigger(Job job, String jobName, String jobGroup, String cronExpression) {
        Class jobClazz = job.getClass();
        String triggerName = jobName+jobClazz.getCanonicalName() + "Trigger";
        String triggerGroup = jobClazz.getCanonicalName() + "TriggerGroup";

        CronTrigger cronTrigger = new CronTrigger();
        cronTrigger.setName(triggerName);
        cronTrigger.setGroup(triggerGroup);
        cronTrigger.setJobName(jobName);
        cronTrigger.setJobGroup(jobGroup);
        try {
            cronTrigger.setCronExpression(cronExpression);//触发任务的时间表达式
        } catch (Exception e) {
            logger.error("",e);
        }

        logger.info("任务 " + jobName + " 触发时间:" + cronExpression);
        return cronTrigger;
    }

    /**
     * 删除job
     *
     * @param jobName
     * @param jobGroup
     */
    public static void removeJob(String jobName, String jobGroup) {
        logger.info("删除任务:jobName:" + jobName + " jobGroup:" + jobGroup);
        Scheduler scheduler = null;
        String[] jobNames = null;
        try {
            scheduler= (StdScheduler)SpringContextUtil.getBean("schedulerFactoryBean");
            jobNames = scheduler.getJobNames(jobGroup);
            if (jobNames == null || jobNames.length == 0) {
                return;
            }
            for (String name : jobNames) {
                if (name.equals(jobName)) {
                    scheduler.pauseTrigger(jobName, jobGroup);//停止触发器
                    scheduler.pauseJob(jobName, jobGroup);//暂停job
                    scheduler.unscheduleJob(jobName, jobGroup);//取消预订的job
                    scheduler.deleteJob(jobName, jobGroup);//删除job
                }
            }

        } catch (SchedulerException e) {
            logger.error("", e);
        }
    }

    /**
     * 获取任务列表
     *
     * @return
     */
    public static Map<String, List<String>> getJobList() {
        Scheduler scheduler = null;
        Map<String, List<String>> map = null;
        try {
            scheduler= (StdScheduler)SpringContextUtil.getBean("schedulerFactoryBean");
            String[] jobGroupNames = scheduler.getJobGroupNames();
            if (jobGroupNames == null || jobGroupNames.length == 0) {
                return null;
            }

            map = new HashMap<String, List<String>>();
            for (String jobGroup : jobGroupNames) {
                String[] jobNames = scheduler.getJobNames(jobGroup);
                if (jobNames == null || jobNames.length == 0) {
                    continue;
                }
                List<String> jobNameList = new ArrayList<String>();
                for (String jobName : jobNames) {
                    jobNameList.add(jobName);
                }
                map.put(jobGroup, jobNameList);
            }
        } catch (SchedulerException e) {
            logger.error("", e);
        }
        logger.info("获取job列表:" + map);
        return map;
    }
}

  6.程序中使用

直接抵用

addJob等即可
 
原文地址:https://www.cnblogs.com/bjlhx/p/7043498.html