springboot集成quartz时,注入bean为null

原因:

        Spring容器可以管理Bean,但是Quartz的job是自己管理的,如果在Job中注入Spring管理的Bean,需要先把Quartz的Job也让Spring管理起来,因此,我们需要重写JobFactory。

解决办法:

       Quartz与Spring集成 Job如何自动注入Spring容器托管的对象

  1. package com.jobs.common.quartz;
  2. import org.quartz.spi.TriggerFiredBundle;
  3. import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
  4. import org.springframework.scheduling.quartz.AdaptableJobFactory;
  5. import org.springframework.stereotype.Component;
  6. /**
  7.  * SpringBoot不能再Quartz中注入Bean,创建任务工厂
  8.  * @author meng
  9.  *
  10.  */
  11. @Component
  12. public class JobFactory extends AdaptableJobFactory {
  13.     /**
  14.      * AutowireCapableBeanFactory接口是BeanFactory的子类
  15.      * 可以连接和填充那些生命周期不被Spring管理的已存在的bean实例
  16.      */
  17.     private AutowireCapableBeanFactory factory;
  18.     
  19.     public JobFactory(AutowireCapableBeanFactory factory) {
  20.         this.factory = factory;
  21.     }
  22.     /**
  23.      * 创建Job实例
  24.      */
  25.     @Override
  26.     protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
  27.         // 实例化对象
  28.         Object job = super.createJobInstance(bundle);
  29.         // 进行注入(Spring管理该Bean)
  30.         factory.autowireBean(job);
  31.         //返回对象
  32.         return job;
  33.     }
  34.     
  35. }

配置schedulerFactoryBean

       Spring为了能集成Quartz,特意提供了管理Quartz的schedulerFactoryBean,必须配置。

  1. package com.jobs.common.quartz;
  2. import org.quartz.Scheduler;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.scheduling.quartz.SchedulerFactoryBean;
  6. /**
  7.  * 任务调度管理器
  8.  * @author meng
  9.  *
  10.  */
  11. @Configuration
  12. public class QuartzConfig {
  13.     private JobFactory jobFactory;
  14.     public QuartzConfig(JobFactory jobFactory){
  15.         this.jobFactory = jobFactory;
  16.     }
  17.     /**
  18.      * 配置SchedulerFactoryBean
  19.      *
  20.      * 将一个方法产生为Bean并交给Spring容器管理
  21.      */
  22.     @Bean
  23.     public SchedulerFactoryBean schedulerFactoryBean() {
  24.         // Spring提供SchedulerFactoryBean为Scheduler提供配置信息,并被Spring容器管理其生命周期
  25.         SchedulerFactoryBean factory = new SchedulerFactoryBean();
  26.     //启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
        factory.setOverwriteExistingJobs(true);
  27.        // 设置自定义Job Factory,用于Spring管理Job bean
  28.         factory.setJobFactory(jobFactory);
  29.         return factory;
  30.     }
  31.     @Bean(name = "scheduler")
  32.     public Scheduler scheduler() {
  33.         return schedulerFactoryBean().getScheduler();
  34.     }

    
}

定时任务管理

  1. package com.jobs.common.quartz;
  2. import org.quartz.CronScheduleBuilder;
  3. import org.quartz.CronTrigger;
  4. import org.quartz.JobBuilder;
  5. import org.quartz.JobDataMap;
  6. import org.quartz.JobDetail;
  7. import org.quartz.JobKey;
  8. import org.quartz.Scheduler;
  9. import org.quartz.SchedulerException;
  10. import org.quartz.Trigger;
  11. import org.quartz.TriggerBuilder;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. import org.springframework.stereotype.Service;
  15. import com.jobs.common.datasource.Constants;
  16. import com.jobs.common.exception.ErrorConfig;
  17. import com.jobs.common.exception.MyException;
  18. import com.jobs.entity.QuartzObject;
  19. /**
  20.  * 任务管理器
  21.  * @author meng
  22.  *
  23.  */
  24. @Service
  25. public class QuartzManager {
  26.     private static final Logger logger= LoggerFactory.getLogger(QuartzManager.class);
  27.     
  28.     private Scheduler scheduler;
  29.     public QuartzManager(Scheduler scheduler){
  30.         this.scheduler = scheduler;
  31.     }
  32.     
  33.     /**
  34.      * 添加一个定时任务
  35.      * @param jobName 定时任务job的名称
  36.      * @param jobGroupName 定时任务所在组的名称
  37.      * @param triggerName 触发器名
  38.      * @param triggerGroupName 触发器组名
  39.      * @param cron 定时任务时间
  40.      * @throws MyException
  41.      */
  42.     public void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName,String cron,String param) throws MyException {
  43.         try {
  44.             // 创建jobDetail实例,绑定Job实现类,指明job的名称,所在组的名称,以及绑定job类
  45.             JobDetail jobDetail = JobBuilder.newJob(ScheduledJob.class).withIdentity(jobName, jobGroupName).build();
  46.             // 定时任务参数
  47.             JobDataMap jobDataMap = jobDetail.getJobDataMap();
  48.             jobDataMap.put("abc", param);
  49.             // 触发器  
  50.             TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
  51.             // 触发器名,触发器组  
  52.             triggerBuilder.withIdentity(triggerName, triggerGroupName);
  53.             triggerBuilder.startNow();
  54.             // 触发器时间设定  
  55.             triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
  56.             // 创建Trigger对象
  57.             CronTrigger trigger = (CronTrigger) triggerBuilder.build();
  58.             // 调度容器设置JobDetail和Trigger
  59.             scheduler.scheduleJob(jobDetail, trigger);
  60.             // 启动  
  61.             if (!scheduler.isShutdown()) {  
  62.                 scheduler.start();  
  63.             }
  64.         } catch (Exception e) {
  65.             logger.error("添加定时任务失败",e.getMessage());
  66.             throw new MyException(ErrorConfig.QUARTZ,"添加定时任务失败");
  67.         }  
  68.     }
  69.  
  70.     /**
  71.      * 暂停定时任务
  72.      * @param name
  73.      * @throws SchedulerException
  74.      * @throws Exception
  75.      */
  76.     public void pauseJob(String name) throws SchedulerException, MyException {
  77.         JobKey jobKey = new JobKey(name, name);
  78.         JobDetail jobDetail = scheduler.getJobDetail(jobKey);
  79.         if (jobDetail == null){
  80.             throw new MyException(ErrorConfig.QUARTZ,"该定时任务不存在");
  81.         }
  82.         scheduler.pauseJob(jobKey);
  83.     }
  84.     
  85.     /**
  86.      * 删除定时任务
  87.      * @param name
  88.      * @throws Exception
  89.      */
  90.     public void deleteJob(String name) throws SchedulerException, MyException {
  91.         JobKey jobKey = new JobKey(name, name);
  92.         JobDetail jobDetail = scheduler.getJobDetail(jobKey);
  93.         if (jobDetail == null){
  94.             throw new MyException(ErrorConfig.QUARTZ,"该定时任务不存在");
  95.         }
  96.         scheduler.deleteJob(jobKey);
  97.     }
  98.     
  99.     /**
  100.      * 重启某个定时任务
  101.      * @param name
  102.      * @throws SchedulerException
  103.      */
  104.     public void resumeJob(String name) throws SchedulerException, MyException {
  105.         JobKey jobKey = new JobKey(name, name);
  106.         JobDetail jobDetail = scheduler.getJobDetail(jobKey);
  107.         if (jobDetail == null)
  108.             throw new MyException(ErrorConfig.QUARTZ,"该定时任务不存在");
  109.         scheduler.resumeJob(jobKey);
  110.     }
  111.     
  112. }
  113.  

编写定时任务

  1. package com.jobs.common.quartz;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileOutputStream;
  5. import java.io.InputStream;
  6. import java.sql.Connection;
  7. import java.sql.ResultSet;
  8. import java.sql.ResultSetMetaData;
  9. import java.sql.SQLException;
  10. import java.sql.Statement;
  11. import java.util.Map;
  12. import org.quartz.Job;
  13. import org.quartz.JobDataMap;
  14. import org.quartz.JobDetail;
  15. import org.quartz.JobExecutionContext;
  16. import org.quartz.JobExecutionException;
  17. import org.slf4j.Logger;
  18. import org.slf4j.LoggerFactory;
  19. import org.springframework.beans.factory.annotation.Autowired;
  20. import org.springframework.stereotype.Service;
  21. import com.jobs.common.datasource.Constants;
  22. import com.jobs.common.mail.MailUtils;
  23. import com.jobs.entity.QuartzObject;
  24. import com.jobs.utils.JdbcUtils;
  25. /**
  26.  * 定时任务,任务执行
  27.  * @author meng
  28.  *
  29.  */
  30. @Service
  31. public class ScheduledJob implements Job{
  32.     private static final Logger logger= LoggerFactory.getLogger(ScheduledJob.class);
  33.     @Autowired
  34.     MailUtils mailUtils;
  35.     
  36.     @Override
  37.     public void execute(JobExecutionContext context) throws JobExecutionException {
  38.          try {
  39.              JobDetail jobDetail = context.getJobDetail();
  40.              JobDataMap jobDataMap = jobDetail.getJobDataMap();
  41.              // 获得参数,执行自己逻辑
  42.          } catch (Exception e) {
  43.              logger.error("【定时任务执行失败:】"+e.getMessage());
  44.              mailUtils.sendQuartzError("【定时任务执行失败:】"+e.getMessage());
  45.          }
  46.         
  47.     }
  48. }

 

已标记关键词 清除标记
scheduler.addJob(jobDetail, true); 并没有存入数据 后台也没有异常,请求哪位前辈指点一下,这是什么原因 其他的配置也都没有问题。 --quartz.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> <bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="dataSource" ref="jboss_dataSource" /> <property name="transactionManager" ref="transactionManager" /> <property name="applicationContextSchedulerContextKey" value="applicationContext" /> <property name="configLocation" value="classpath:quartz.properties" /> <!--这个是必须的,QuartzScheduler 延启动,应用启动完后 QuartzScheduler 再启动 --> <property name="startupDelay" value="5" /> <!--这个是可选,QuartzScheduler 启动更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 --> <property name="overwriteExistingJobs" value="true" /> <property name="jobDetails"> <list> <ref bean="testBatch" /> </list> </property> </bean> <bean id="testBatch" class="com.sinosoft.core.spring.quartz.MethodInvokingJobDetailFactoryBean"> <!--shouldRecover属性为true,则当Quartz服务被中止后,再次启动任务会尝试恢复执行之前未完成的所有任务 --> <property name="shouldRecover" value="true" /> <property name="durable" value="true" /> <property name="targetObject" ref="TestBatch" /> <property name="targetMethod" value="runTestBatch" /> </bean> </beans> --quartZ.properties org.quartz.scheduler.instanceName = DefaultQuartzScheduler org.quartz.scheduler.instanceId = AUTO org.quartz.scheduler.rmi.export = false org.quartz.scheduler.rmi.proxy = false org.quartz.scheduler.wrapJobExecutionInUserTransaction = false org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 10 org.quartz.threadPool.threadPriority = 5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true org.quartz.jobStore.misfireThreshold = 60000 org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegate #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.WebLogicDelegate #org.quartz.jobStore.useProperties = true org.quartz.jobStore.tablePrefix = QRTZ_ org.quartz.jobStore.isClustered = false #org.quartz.jobStore.clusterCheckinInterval = 300000 org.quartz.jobStore.maxMisfiresToHandleAtATime=1
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页