`
wangshiyang
  • 浏览: 69215 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

spring+quartz任务动态添加

阅读更多
注意:只适用于quartz1.8版本以下的,1.8版本以上的因为spring需要等等3.2M2版本才能修复
结合spring+quartz开发个后台的WEB管理系统,系统主要包括以下功能:

  1、动态添加、修改和删除数据源,并加入到spring管理。
  2、动态注册、修改和删除任务(需要实现的具体quartz业务类),并加入到quartz管理。
  3、提供上传第三方包的功能。(主要考虑实现的业务类,需要引入其他的jar包)。
  4、在线日志查询分析。
  。。。

   后台系统的应用领域:

  1、执行多个数据库之间的数据交换服务。
  2、架设系统与银行之间的通讯服务。
  。。。

  以前没搞过这方面应用,比较头疼,经过google、百度,初步方案实现如下:
 
  1、实现个servlet用于启动quartz调度。
  
 
  程序如下:

Java代码 
 public class DispatchJobServlet extends HttpServlet {  
  
private static final long serialVersionUID = -3920177706344758439L;  
private ApplicationContext ctx;  
  
public DispatchJobServlet() {  
    super();  
    //  初始化自定义类加载器,主要用于加载第三方包和服务程序。  
    ServiceStartup manguage = new ServiceStartup();  
    manguage.startUp();  
}  
  
/** 
 * 初始化 
 */  
public void init(ServletConfig config) throws ServletException {  
    super.init(config);  
    ctx = WebApplicationContextUtils  
            .getRequiredWebApplicationContext(config.getServletContext());  
    StartJobService taskStartService = (StartJobService) ctx.getBean("startJobService");  
    //启用个线程开始任务调度  
    ExecutorService exec = Executors.newCachedThreadPool();  
    exec.execute(taskStartService);  
}  

 
  


   2、到xml文件查询前台添加的任务队列,加入quartz管理并执行。
   
  
Java代码 
@Service  
public class StartJobService implements Runnable {  
    /** 
     * log4j 记录器 
     */  
    private static final Logger log = Logger.getLogger(StartJobService.class);  
    @Resource  
    private SchedulerService schedulerService;  
  
    public void run() {  
        try {  
            while (true) {  
                List<JobBo> list = DomParser.findAllJobXml("db.service.xml");  
                Iterator<JobBo> i = list.iterator();  
                while (i.hasNext()) {  
                    JobBo job = i.next();  
                    // 如果任务队列不存在则注册并运行  
                    if (!ServiceManager.queryExistsJob(job.getName())) {  
                        try {  
                            schedulerService.schedule(job);  
                            ServiceManager.getJobHolder().put(job.getName(),  
                                    job);  
                        } catch (Exception e) {  
                            log.error("服务【" + job.getName() + "】启动失败!", e);  
                            throw new SummerException("服务【" + job.getName()  
                                    + "】启动失败!");  
                        }  
                    }  
                    Thread.sleep(3000);  
                }  
            }  
        } catch (SummerException e) {  
            throw e;  
        } catch (Exception e) {  
            log.error("调度任务出现异常!", e);  
        }  
    }  
}  


   3、封装SchedulerService实现quartz调度的方法
   封装的出来quartz的接口:
 
Java代码 
public interface SchedulerService {  
  
    /** 
     * 自定义任务对象并启动任务 
     *  
     * @param job 
     *            任务队列业务对象 
     */  
    void schedule(JobBo job);  
  
    /** 
     * 取得所有调度Triggers 
     *  
     * @return 
     */  
    List<Map<String, Object>> getQrtzTriggers();  
  
    /** 
     * 根据名称和组别暂停Tigger 
     *  
     * @param triggerName 
     * @param group 
     */  
    void pauseTrigger(String triggerName, String group);  
  
    /** 
     * 恢复Trigger 
     *  
     * @param triggerName 
     * @param group 
     */  
    void resumeTrigger(String triggerName, String group);  
  
    /** 
     * 删除Trigger 
     *  
     * @param triggerName 
     * @param group 
     */  
    boolean removeTrigdger(String triggerName, String group);  
}  



   实现类:

Java代码 
public class SchedulerServiceImpl implements SchedulerService {  
  
    private static final Logger log = LoggerFactory  
            .getLogger(SchedulerServiceImpl.class);  
  
    private Scheduler scheduler;  
  
    private JobDetail jobDetail;  
  
    public void setScheduler(Scheduler scheduler) {  
        this.scheduler = scheduler;  
    }  
  
    public void setJobDetail(JobDetail jobDetail) {  
        this.jobDetail = jobDetail;  
    }  
  
    /** 
     * 自定义任务对象并启动任务 
     */  
    public void schedule(JobBo job) {  
        // trigger分类  
        String category = job.getCategory();  
        try {  
            if ("cron".equals(category)) {  
                scheduleCron(job);  
            } else {  
                scheduleSimple(job);  
            }  
        } catch (Exception e) {  
            log.error("任务调度过程中出现异常!");  
            throw new SummerException(e);  
        }  
    }  
  
    /** 
     * simple任务触发 
     *  
     * @param job 
     */  
    private void scheduleSimple(JobBo job) {  
        String name = getTriggerName(job.getName());  
        // 实例化SimpleTrigger  
        SimpleTrigger simpleTrigger = new SimpleTrigger();  
  
        // 这些值的设置也可以从外面传入,这里采用默放值  
        simpleTrigger.setJobName(jobDetail.getName());  
        simpleTrigger.setJobGroup(Scheduler.DEFAULT_GROUP);  
        simpleTrigger.setRepeatInterval(1000L);  
        // 设置名称  
        simpleTrigger.setName(name);  
  
        // 设置Trigger分组  
        String group = job.getGroup();  
        if (StringUtils.isEmpty(group)) {  
            group = Scheduler.DEFAULT_GROUP;  
        }  
        simpleTrigger.setGroup(group);  
  
        // 设置开始时间  
        Timestamp startTime = job.getStartTime();  
        if (null != startTime) {  
            simpleTrigger.setStartTime(new Date());  
        }  
  
        // 设置结束时间  
        Timestamp endTime = job.getEndTime();  
        if (null != endTime) {  
            simpleTrigger.setEndTime(endTime);  
        }  
  
        // 设置执行次数  
        int repeatCount = job.getRepeatCount();  
        if (repeatCount > 0) {  
            simpleTrigger.setRepeatCount(repeatCount);  
        }  
  
        // 设置执行时间间隔  
        long repeatInterval = job.getRepeatInterval();  
        if (repeatInterval > 0) {  
            simpleTrigger.setRepeatInterval(repeatInterval * 1000);  
        }  
        try {  
            JobDataMap jobData = new JobDataMap();  
            jobData.put("name", job.getName());  
            jobData.put("desc", job.getDesc());  
            jobDetail.setJobDataMap(jobData);  
            scheduler.addJob(jobDetail, true);  
            scheduler.scheduleJob(simpleTrigger);  
            scheduler.rescheduleJob(simpleTrigger.getName(), simpleTrigger  
                    .getGroup(), simpleTrigger);  
        } catch (SchedulerException e) {  
            log.error("任务调度出现异常!");  
            log.error(LogGenerator.getInstance().generate(e));  
            throw new SummerException("任务调度出现异常!");  
        }  
    }  
  
    /** 
     * cron任务触发 
     *  
     * @param job 
     */  
    private void scheduleCron(JobBo job) {  
        String name = getTriggerName(job.getName());  
        try {  
            JobDataMap jobData = new JobDataMap();  
            jobData.put("name", job.getName());  
            jobData.put("desc", job.getDesc());  
            jobDetail.setJobDataMap(jobData);  
            scheduler.addJob(jobDetail, true);  
            CronTrigger cronTrigger = new CronTrigger(name, job.getGroup(),  
                    jobDetail.getName(), Scheduler.DEFAULT_GROUP);  
            cronTrigger.setCronExpression(job.getCronExpression());  
            scheduler.scheduleJob(cronTrigger);  
            scheduler.rescheduleJob(cronTrigger.getName(), cronTrigger  
                    .getGroup(), cronTrigger);  
        } catch (Exception e) {  
            log.error("执行cron触发器出现异常!", e);  
            throw new SummerException("执行cron触发器出现异常!");  
        }  
    }  
  
    public void schedule(String name, Date startTime, Date endTime,  
            int repeatCount, long repeatInterval, String group) {  
        if (name == null || name.trim().equals("")) {  
            name = UUID.randomUUID().toString();  
        } else {  
            // 在名称后添加UUID,保证名称的唯一性  
            name += "&" + UUID.randomUUID().toString();  
        }  
        try {  
            scheduler.addJob(jobDetail, true);  
            SimpleTrigger SimpleTrigger = new SimpleTrigger(name, group,  
                    jobDetail.getName(), Scheduler.DEFAULT_GROUP, startTime,  
                    endTime, repeatCount, repeatInterval);  
            scheduler.scheduleJob(SimpleTrigger);  
            scheduler.rescheduleJob(SimpleTrigger.getName(), SimpleTrigger  
                    .getGroup(), SimpleTrigger);  
        } catch (SchedulerException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    public void pauseTrigger(String triggerName, String group) {  
        try {  
            scheduler.pauseTrigger(triggerName, group);// 停止触发器  
        } catch (SchedulerException e) {  
            throw new SummerException(e);  
        }  
    }  
  
    public void resumeTrigger(String triggerName, String group) {  
        try {  
            scheduler.resumeTrigger(triggerName, group);// 重启触发器  
        } catch (SchedulerException e) {  
            log.error("重启触发器失败!");  
            throw new SummerException(e);  
        }  
    }  
  
    public boolean removeTrigdger(String triggerName, String group) {  
        try {  
            scheduler.pauseTrigger(triggerName, group);// 停止触发器  
            return scheduler.unscheduleJob(triggerName, group);// 移除触发器  
        } catch (SchedulerException e) {  
            throw new SummerException(e);  
        }  
    }  
  
    private Timestamp parseDate(String time) {  
        try {  
            return Timestamp.valueOf(time);  
        } catch (Exception e) {  
            log.error("日期格式错误{},正确格式为:yyyy-MM-dd HH:mm:ss", time);  
            throw new SummerException(e);  
        }  
    }  
  
    public List<Map<String, Object>> getQrtzTriggers() {  
        // TODO Auto-generated method stub  
        return null;  
    }  
  
    /** 
     * 获取trigger名称 
     *  
     * @param name 
     * @return 
     */  
    private String getTriggerName(String name) {  
        if (StringUtils.isBlank(StringUtils.trim(name))) {  
            name = UUID.randomUUID().toString();  
        } else {  
            name = name.substring(name.lastIndexOf(".") + 1);  
            // 在名称后添加UUID,保证名称的唯一性  
            name += "&" + UUID.randomUUID().toString();  
        }  
        return StringUtils.trim(name);  
    }  
}  



  4、覆盖QuartzJobBean的executeInternal方法,根据“name”名实现任务的动态分配
Java代码 
public class EnhanceQuartzJobBean extends QuartzJobBean {  
    /** 
     * log4j 记录器 
     */  
    private static final Logger log = Logger  
            .getLogger(EnhanceQuartzJobBean.class);  
  
    @Override  
    protected void executeInternal(JobExecutionContext context)  
            throws JobExecutionException {  
        try {  
            JobDetail t = context.getJobDetail();  
            JobDataMap map = t.getJobDataMap();  
            String name = map.getString("name");  
            String desc = map.getString("desc");  
            ServiceStartupManguage manguage = new ServiceStartupManguage();  
            manguage.runService(name, desc);  
        } catch (Exception e) {  
            log.error("执行任务出现异常", e);  
        }  
    }  
      
    public class ServiceStartup {  
    /** 
     * log4j 记录器 
     */  
    private static final Logger log = Logger  
            .getLogger(ServiceStartupManguage.class);  
  
    public void startUp() {  
        // 启动动态重新加载类的服务  
        StringBuilder sb = new StringBuilder(1024);  
        sb.append(ServiceManager.getHome() + "work");  
        String jarPath = ServiceManager.getHome() + "ext";  
        // 遍历ext文件夹,寻找jar文件  
        File dir = new File(jarPath);  
        String[] subFiles = dir.list();  
        for (int i = 0; i < subFiles.length; i++) {  
            File file = new File(jarPath + System.getProperty("file.separator")  
                    + subFiles[i]);  
            if (file.isFile() && subFiles[i].endsWith("jar")) {  
                sb.append(File.pathSeparator + jarPath  
                        + System.getProperty("file.separator") + subFiles[i]);  
            }  
        }  
        ServiceManager.checker = new ClassModifyChecker(ServiceManager.getHome());  
        ServiceManager.loader = new ServiceClassLoad(DispatchJobServlet.class  
                .getClassLoader(), (String) sb.toString(), ServiceManager.checker);  
        ServiceManager.classPath = sb.toString();  
    }  
  
    /** 
     * 启动后台服务 
     *  
     * @author 任鹤峰 2009-02-03 
     * @param name 
     * @param desc 
     * @throws ClassNotFoundException 
     * @throws NoSuchMethodException 
     * @throws InstantiationException 
     * @throws IllegalAccessException 
     * @throws InvocationTargetException 
     */  
    @SuppressWarnings("unchecked")  
    public void runService(String name, String desc)  
            throws ClassNotFoundException, NoSuchMethodException,  
            InstantiationException, IllegalAccessException,  
            InvocationTargetException {  
        try {  
            Object service;  
            Class cls = null;  
            if (null != ServiceManager.loader) {  
                cls = ServiceManager.getLoader().loadClass(name);  
            } else {  
                cls = Class.forName(name);  
            }  
            Class[] par = null;  
            Object[] obj = null;  
            par = new Class[2];  
            par[0] = String.class;  
            par[1] = String.class;  
            obj = new Object[2];  
            obj[0] = name;  
            obj[1] = desc;  
            Constructor ct = cls.getConstructor(par);  
            service = ct.newInstance(obj);  
            Method meth = cls.getMethod("start");  
            meth.invoke(service);  
            cls = null;  
        } catch (Exception e) {  
            log.error("运行注册服务【" + name + "】出现异常", e);  
        }  
    }  
}  
      
}  



  5、quartz的配置文件:

Java代码 
<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"  
 "http://www.springframework.org/dtd/spring-beans.dtd">  
<beans>  
    <bean id="schedulerFactory" singleton="false"  
        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
        <property name="applicationContextSchedulerContextKey" value="applicationContextKey" />  
        <property name="configLocation" value="classpath:quartz.properties" />  
    </bean>  
  
    <bean id="jobDetail" singleton="false"  
        class="org.springframework.scheduling.quartz.JobDetailBean">  
        <property name="jobClass">  
            <value>  
                com.xeranx.summer.scheduling.EnhanceQuartzJobBean  
            </value>  
        </property>  
    </bean>  
    <bean id="schedulerService" singleton="false"  
        class="com.xeranx.summer.scheduling.service.SchedulerServiceImpl">  
        <property name="jobDetail">  
            <ref bean="jobDetail" />  
        </property>  
        <property name="scheduler">  
            <ref bean="schedulerFactory" />  
        </property>  
    </bean>  
</beans>  



以上是实现的主要代码: 目前可以实现任务的动态添加并执行,现在的问题是添加多个任务时,最后面的任务会覆盖之前所有的任务。
分享到:
评论

相关推荐

    spring+springMVC+mybatis+quartz动态定时任务创建

    在IT行业中,构建高效、可扩展的Web应用是至关重要的,而"spring+springMVC+mybatis+quartz动态定时任务创建"就是一个常见的技术栈,用于实现这样的目标。这个组合充分利用了各组件的优势,提供了强大的后端服务支持...

    spring+quartz动态定时任务创建 +mybatis

    **Spring+Quartz动态定时任务创建** 将Spring与Quartz结合,我们可以方便地在运行时动态创建和修改定时任务。首先,我们需要在Spring配置文件中声明一个SchedulerFactoryBean,然后定义JobDetail和Trigger,分别表示...

    spring+quartz 动态任务方案

    ### Spring + Quartz 动态任务方案详解 #### 一、Spring与Quartz简介及整合背景 Spring 是一款轻量级的 Java 开发框架,旨在简化企业级应用开发过程中的复杂性,提供了一套完整的解决方案,包括但不限于依赖注入、...

    定时框架spring+quartz

    1. **引入依赖**:首先,在项目的pom.xml文件中添加Quartz和Spring相关依赖。 2. **配置Quartz**:在Spring的配置文件(如applicationContext.xml)中,定义Quartz的相关bean,包括SchedulerFactoryBean、JobDetail...

    Spring mvc + Mybatis + quartz + swagger 定时任务管理[新增、编辑、删除、修改]

    3. Quartz通过监听数据库中的变化,自动识别出新添加或修改的任务,并根据配置信息生成对应的Job和Trigger。 4. 当触发条件满足时,Quartz执行相应的Job,同时记录任务的运行日志,这部分日志信息也会被写入到数据库...

    spring+quartz+maven项目实例

    Quartz可以很好地与Spring集成,通过Spring的ApplicationContext,我们可以方便地管理和控制Quartz的Scheduler,实现任务的动态添加、修改和删除。 【Maven】 Maven是Java项目管理工具,负责项目的构建、依赖管理和...

    Spring+Quartz example

    如果需要动态添加、修改或删除任务,可以利用Spring的`SchedulerFactoryBean`提供的API进行操作。 Quartz的强大之处在于它的灵活性,可以设置复杂的调度规则,比如Cron表达式,可以实现按日期、时间间隔等多种方式...

    Spring+Quartz 集群

    在IT行业中,Spring框架是Java企业级应用开发的首选,而Quartz则是一个强大的任务调度库,常用于实现定时任务。本篇文章将深入探讨如何在Spring环境中集成Quartz以构建一个高可用的集群。 首先,我们需要理解Spring...

    spring+quartz实现动态设置定时任务

    Spring和Quartz是两个强大的工具,可以协同工作来实现动态管理的定时任务。本文将深入探讨如何利用Spring框架和Quartz库创建和管理这些任务。 **Spring框架** 是一个广泛应用的Java企业级开发框架,它提供了丰富的...

    spring+mvc+quartz.rar

    《Spring MVC + Quartz 整合实现定时任务管理》 在现代企业级应用中,系统往往需要执行一些定时任务,如数据同步、报表生成等。Spring框架以其强大的功能和灵活的扩展性,成为Java开发的首选,而Quartz作为一款开源...

    Spring + Quartz配置实例(转载)

    Quartz是一个开源的作业调度库,它允许开发者安排任务以在特定时间执行,而Spring框架则是一个广泛使用的应用开发框架,尤其在企业级Java应用程序中。 在Spring中集成Quartz,主要涉及到以下几个关键知识点: 1. *...

    spring boot + quartz 动态管理 分布式

    在动态管理定时任务方面,Spring Boot结合Quartz可以实现对定时任务的添加、修改、删除等操作。开发者可以使用Spring的@Scheduled注解或者自定义Job类,配合Quartz的Scheduler接口,轻松地定义和控制任务。例如,...

    Spring+Quartz 从数据库中获取定时任务和定时时间,动态实现对定时任务的增删改查

    本项目旨在演示如何利用Spring和Quartz从数据库中动态加载定时任务,并实现对它们的增删改查功能。以下是关于这个主题的详细知识讲解。 首先,Quartz是一个开源的作业调度框架,它允许开发者创建、安排和执行定时...

    spring3.0+quartz-1.6.0定时

    Spring 3.0 和 Quartz 1.6.0 结合使用是企业级应用中常见的定时任务解决方案。Spring 是一个强大的Java应用程序框架,提供了依赖注入、AOP(面向切面编程)以及众多其他功能,而Quartz则是一个开源的作业调度框架,...

    spring+quartz实现定时任务动态管理

    本项目旨在实现对Quartz定时任务的动态管理,包括添加、停止和恢复等操作。前端采用jQuery和Bootstrap构建,提供用户友好的可视化界面,同时应用了MyBatis分页插件来优化数据查询性能。 首先,让我们详细了解一下...

    spring+mybatis+quartz

    Quartz可以与Spring无缝集成,使得在Spring应用中定义和管理定时任务变得简单。开发者可以创建Job类来定义任务逻辑,并使用Trigger定义触发任务的时间规则。 在整合这三个技术时,通常会使用Spring的...

    Spring+quartz相关jar包.rar

    1. 添加依赖:在项目中引入 Spring 和 Quartz 相关的 jar 包。这些 jar 包可能包括 spring-context、spring-context-support 和 quartz-jobs、quartz-core 等。 2. 配置 Scheduler:在 Spring 配置文件中,设置 ...

    基于SSM+quartz的定时任务管理demo

    SpringBoot提供了对Quartz的自动配置,只需添加相关依赖,配置文件中设置一些属性,即可快速启动定时任务服务。 **8. 管理界面** 为了方便管理和监控定时任务,可以开发一个Web界面,利用Quartz提供的API查询Job和...

    Spring+Quartz定时调度

    **Spring+Quartz定时调度详解** 在Java世界中,实现定时任务调度是非常常见...配合提供的文档和示例代码,如`Spring+Quartz任务调度.docx`和解压后的`spring+quartz.rar`文件,开发者可以快速掌握并应用到实际项目中。

    Spring+Quartz实现任务调度的小例子

    Spring框架和Quartz是两个广泛使用的工具,它们可以协同工作以实现复杂和灵活的任务调度。本篇文章将深入探讨如何使用Spring与Quartz结合来创建一个任务调度的小例子。 首先,Spring是一个开源的Java企业级应用开发...

Global site tag (gtag.js) - Google Analytics