spring quartz配置使用

spring quartz配置使用

前期项目使用spring task配置的,由于执行是单线程方式,一个定时任务执行太久会影响下一个定时任务执行,所以改用spring quartz 多个线程并发的方式

前期准备:导入jar包

List quartz = ['org.quartz-scheduler:quartz:2.3.2']

dependencies {
    compile lombok, spring, quartz......
    testCompile junit, mock
    compile ("掩码-adm:2.0.2"){
        exclude module: "dom4j"
    }
}

List quartz = ['org.quartz-scheduler:quartz:2.3.2']

1.task封装类

public class TaskConfig {
    private String jobName;
    private String jobGroup;
    private String triggerName;
    private String triggerGroup;
    private String cronExpression;
    private Class configClass;

    public static TaskConfig newTaskConfig() {
        return new TaskConfig();
    }
    public TaskConfig withJobName(String jobName) {
        this.jobName = jobName;
        return this;
    }
    public TaskConfig withJobGroup(String jobGroup) {
        this.jobGroup = jobGroup;
        return this;
    }
    public TaskConfig withTriggerName(String triggerName) {
        this.triggerName = triggerName;
        return this;
    }
    public TaskConfig withTriggerGroup(String triggerGroup) {
        this.triggerGroup = triggerGroup;
        return this;
    }
    public TaskConfig withCronExpression(String cronExpression) {
        this.cronExpression = cronExpression;
        return this;
    }
    public TaskConfig withConfigClass(Class configClass) {
        this.configClass = configClass;
        return this;
    }
    // ...... get,set
}

2.quartz初始化类,将所有的定时任务注入IOC

import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

@Lazy(false)
@Service
public class QuratzTaskService {

    @Autowired
    private Scheduler scheduler;

    @PostConstruct
    public int init() {
        int count = 0;
        try {
            List<TaskConfig> list = doLoadTaskConfig();
            for (TaskConfig taskConfig : list) {
                String jobName = "jobName";
                String jobGroup = "jobGroup";
                JobDetail jobDetail =
                        JobBuilder.newJob(taskConfig.getConfigClass()).withIdentity(jobName, jobGroup).build();
                // trigger和job共用一套name和group
                CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup)
                        .withSchedule(CronScheduleBuilder.cronSchedule(taskConfig.getCronExpression())).forJob(jobName, jobGroup).build();
                scheduler.scheduleJob(jobDetail, trigger);
            }
            scheduler.start();
            count = list.size();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return count;
    }

    private List<TaskConfig> doLoadTaskConfig() {
        // 可以将定时任务存储到MySQL数据库,拉取列表处理
        List<TaskConfig> list = new ArrayList<>();
        TaskConfig config = TaskConfig.newTaskConfig()
                .withConfigClass(HoldPositionsTask.class)
                .withCronExpression("0 */2 * * * ?");
        list.add(config);
        TaskConfig config1 = TaskConfig.newTaskConfig()
                .withConfigClass(HoldAumTask.class)
                .withCronExpression("*/20 * * * * ?");
        list.add(config1);
        return list;
    }
}

3.定义定时任务

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Service;

@Service
public class HoldPositionsTask implements Job {

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("quartzTaskExecute..." + this.getClass().getName() + "定时任务开始执行.....");
        // doSomethings...
    }
}

跑了一把,IOC容器没有起来。。。。。

报错如下

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'quratzTaskService': Unsatisfied dependency expressed through field 'scheduler'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.quartz.Scheduler' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1420)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
	at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:401)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:292)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
	at cn.webank.weup.biz.web.listeners.WeupSpringContextLoaderListener.contextInitialized(WeupSpringContextLoaderListener.java:28)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4697)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5163)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1412)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1402)
	at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
	at java.util.concurrent.FutureTask.run(FutureTask.java)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.quartz.Scheduler' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1717)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1273)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
	... 26 more
WeupSpringContextLoaderListener.contextInitialized|spring ApplicationContext 启动失败
Disconnected from the target VM, address: '127.0.0.1:59788', transport: 'socket'

Process finished with exit code 1

这个是因为 @Autowired   private Scheduler scheduler;实现类没有注入IOC,补充两个类

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

/**
 * 结合QuartzConfig,将Quartz的Job交由Spring管理,解决@Autowired变量为空的问题
 *
 */
public class QuartzJobFactory extends SpringBeanJobFactory {

    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        // 调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        // 进行注入
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}
import org.quartz.Scheduler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

/**
 * 将Scheduler的Bean交由Spring管理
 */
@Configuration
public class QuartzConfig {

    @Bean
    public Scheduler scheduler(SchedulerFactoryBean schedulerFactoryBean) {
        return schedulerFactoryBean.getScheduler();
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(QuartzJobFactory jobFactory) {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setJobFactory(jobFactory);
        return schedulerFactoryBean;
    }

    @Bean
    public QuartzJobFactory jobFactory() {
        return new QuartzJobFactory();
    }
}

再次启动项目,报错就没了。部署Linux上定时任务页正常跑起来了

这里的日志是公司内部的一个日志框架打印的。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值