003-spring结合java类调用quartz

一、利弊

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

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

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

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

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

  1.编写ApplicationContext对象注入类

public class SpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext context)
            throws BeansException {
        SpringContextUtil.applicationContext = context;
    }
    public static Object getBean(String name){
        return applicationContext.getBean(name);
    }
}

  2.spring,xml配置

<bean id="spring" class="com.jd.ofc.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等即可
时间: 2024-10-11 13:18:07

003-spring结合java类调用quartz的相关文章

普通java类调用spring中的bean

使用ssm项目,很多service,dao等都使用了注解方式定义,普通java类要获取到这些bean,可这么写: public class Common { private UserService userService; public Common() { @SuppressWarnings("resource") AbstractApplicationContext ctx = new ClassPathXmlApplicationContext(new String []{&qu

普通java类调用spring中的bean(二)

上一篇使用new ClassPathXmlApplicationContext 可以获取到spring上下文,但是有个问题: 因为它会每次都重新装载applicationContext-common.xml并实例化上下文bean, 如果有些线程配置类也是在这个配置文件中,那么会造成做相同工作的的线程会被启两次.一次是web容器初始化时启动,另一次是上述代码显示的实例化了一次.这在业务上是要避免的. 从性能上考虑,最好还是增加一个工具类,用来取得上下文ApplicationContext,这个工具

Spring MVC普通类或工具类中调用service报空空指针的解决办法(调用service报java.lang.NullPointerException)

当我们在非Controller类中应用service的方法是会报空指针,如图: 这是因为Spring MVC普通类或工具类中调用service报空null的解决办法(调用service报java.lang.NullPointerException) 按上述步骤解决完自己的工具类后,你会发现项目运行后仍然报空指针此时你需要在applicationContext.xml 配置文件中添加一行配置文件 如图: 对自己工具类所在的包进行注解扫描,使Spring能够识别自己上面所配置的注解 原文地址:htt

Spring结合java Quartz配置实例代码

原文:Spring结合java Quartz配置实例代码 源代码下载地址:http://www.zuidaima.com/share/1787232442715136.htm 各种企业应用几乎都会碰到任务调度的需求,就拿论坛来说:每隔半个小时生成精华文章的RSS文件,每天凌晨统计论坛用户的积分排名,每隔30分钟执行锁定用户解锁任务.对于一个典型的MIS系统来说,在每月1号凌晨统计上个月各部门的业务数据生成月报表,每半个小时查询用户是否已经有快到期的待处理业务--,这样的例子俯拾皆是,不胜枚举.

【Spring】IOC之基于Java类的配置Bean

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 基于Java配置选项,可以编写大多数的Spring不用配置XML,但有几个基于Java的注释的帮助下解释.从Spring3.0开始支持使用java代码来代替XML来配置Spring,基于Java配置Spring依靠Spring的JavaConfig项目提供的很多优点.通过使用@Configuration, @Bean ,@Importand,@DependsOnannotations来实现J

(转)在JSP中调用JAVA类和使用JavaBean有什么区别?

在JSP中调用JAVA类和使用JavaBean有什么区别? 可以像使用一般的类一样使用JavaBean,Bean只是一种特殊的类.特殊在可以通过<jsp:useBean   />调用JavaBean而其他类,可以和一般java中一样使用.  Bean的参数中还可以指定范围, <jsp:useBean  scope="application"   />该Bean在服务器的JVM中将只有一个实例. Bean是和WebServer相关的,不同的页面可以通过Bean 交

java springboot调用第三方接口 借助hutoool工具类 爬坑

楼主是个后端小白一枚,之前没接触过后端,只学了java基本语法,还是在学校老师教的,学的很浅,什么ssh.ssm框架都没有学,最近在自学spring boot,看书学也看不是很懂,就在b站上看教学视频,大概看了几个老师讲的,最后选了尚硅谷的视频,老师讲的很好,有点偏向底层源码解析,讲的很细,对我这个新手小白来说也不知道好不好,反正我就是跟着看了.最近接到超哥布置的一个任务,spring boot调用第三方接口,下面就讲讲我这个新手小白是怎么一步一步磕出来结果的,顺便记录一下,免得我后面忘了. 首

java类中调用servlet

一.Java中调用servlet说明: 我们有时可能需要在Java类中调用Servlet从而实现某些特殊的功能,在JavaAPI中提供了一个URL的类,其中openStream( )方法可以打开URL的连接,并返回一个用于该连接读入的InputStream. 二.Java中调用servlet应用举例: package com.solid.test; import java.io.BufferedReader; import java.io.IOException; import java.io.

kettle中调用java类

有时需要在kettle调用java类,如:验证.查询或自定义加密等.有时甚至连基本的数据访问都不那么简单,如获取一个存储文件或使用一个数据库连接,某些数据源可能封装在应用程序中,手工使用自定义的java客户端访问是唯一的方法.本文介绍如何在kettle中调用java类.示例代码在这里下载. 注:如果你使用kettle4.0及以上版本,也你也可以使用user defined java class 步骤实现.   Modified Java ScriptValue 步骤 关键要在kettle中使用M