跨年篇:祝愿大家万事随心,吃饭吃得饱,睡觉睡得好,没有烦扰。
我在Job实现类中使用@Resource和@Autowired注入mapper类时,出现了如下的错误:
2020-12-31 20:41:07.311 ERROR 22456 --- [eduler_Worker-5] org.quartz.core.ErrorLogger : Job (repeat.test2 threw an exception.org.quartz.SchedulerException: Job threw an unhandled exception.at org.quartz.core.JobRunShell.run(JobRunShell.java:213)at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: java.lang.NullPointerException: nullat com.example.docker_images.job.HelloJob.execute(HelloJob.java:26)at org.quartz.core.JobRunShell.run(JobRunShell.java:202)... 1 common frames omitted
答:出现这个原因是没有注入成功,所以为null,再通过这个对象调用mapper的方法不报错才怪。
答:这里我来解释一下,这个是因为Job的实现类并没有加入到spring容器中,自然无法使用自动注入。
答:自然是将Job加入到Spring容器中,然后就可以执行自动注入了。 事先申明一下,这篇文章是在quartz(三)任务持久化-jdbc篇(一看就会)上优化的,有兴趣的可以看一下三。注入方式如下:
通用代码(在三的基础上加了数据库的操作):
import com.example.docker_images.entity.User;
import com.example.docker_images.entity.common.CwConstant;
import com.example.docker_images.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;import javax.annotation.Resource;
import java.util.List;@Slf4j
public class HelloJob implements Job {@Resourceprivate IUserService iUserService;@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {//通过jobDetail获取数据String payload = context.getTrigger().getJobDataMap().getString(CwConstant.PAYLOAD);System.out.println(payload);System.out.println("hello world!!!");List
}
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;public final class ApplicationContextHolder extends SpringBeanJobFactoryimplements ApplicationContextAware {private static ApplicationContext context;private transient AutowireCapableBeanFactory beanFactory;@Overridepublic void setApplicationContext(final ApplicationContext context) {beanFactory = context.getAutowireCapableBeanFactory();ApplicationContextHolder.context = context;}@Overrideprotected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {final Object job = super.createJobInstance(bundle);beanFactory.autowireBean(job);return job;}public static ApplicationContext getContext() {return context;}
}
import com.example.docker_images.job.ApplicationContextHolder;
import org.quartz.Scheduler;
import org.quartz.spi.JobFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;import java.io.IOException;@Configuration
public class QuartzConfiguration {@Autowiredprivate ApplicationContext applicationContext;/*** Create the job factory bean** @return Job factory bean*/@Beanpublic JobFactory jobFactory() {ApplicationContextHolder jobFactory = new ApplicationContextHolder();jobFactory.setApplicationContext(applicationContext);return jobFactory;}/*** Create the Scheduler Factory bean** @return scheduler factory object*/@Beanpublic SchedulerFactoryBean schedulerFactory() {SchedulerFactoryBean factory = new SchedulerFactoryBean();factory.setAutoStartup(true);factory.setSchedulerName("CarWash Scheduler");factory.setOverwriteExistingJobs(true);factory.setJobFactory(jobFactory());return factory;}/*** 获得Scheduler 对象** @return* @throws IOException*/@Beanpublic Scheduler scheduler() throws IOException {return schedulerFactory().getScheduler();}
}
import com.example.docker_images.entity.common.APIResult;
import com.example.docker_images.entity.common.CwConstant;
import com.example.docker_images.entity.common.ReturnCodeEnum;
import com.example.docker_images.entity.job.JobPayload;
import com.example.docker_images.job.HelloJob;
import com.example.docker_images.service.JobService;
import com.example.docker_images.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.TriggerBuilder.newTrigger;@Slf4j
@Service
public class JobServiceImpl implements JobService {//这里不可以使用@Resource来注入,必须使用@Autowired@Autowiredprivate SchedulerFactoryBean schedulerFactory;@Overridepublic APIResult initiate(JobPayload payload) {try {Scheduler scheduler = schedulerFactory.getScheduler();JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity(payload.getName(), payload.getGroup()).build();switch (payload.getScheduleType()){case CwConstant.JobType.NOW:Trigger build = newTrigger().withIdentity(payload.getName(), payload.getGroup()).startNow().usingJobData(CwConstant.PAYLOAD,payload.getDataMap()).withDescription(payload.getDesc()).build();scheduler.scheduleJob(jobDetail,build);scheduler.start();log.info("成功创建即刻执行任务!!!");break;case CwConstant.JobType.ONCE:Trigger trigger = newTrigger().withIdentity(payload.getName(), payload.getGroup()).startAt(DateUtil.parseYYYYMMDD(payload.getCron())).usingJobData(CwConstant.PAYLOAD,payload.getDataMap()).withDescription(payload.getDesc()).build();scheduler.scheduleJob(jobDetail,trigger);scheduler.start();log.info("成功创建未来执行一次任务!!!");break;case CwConstant.JobType.REPEAT:CronTrigger cronTrigger = newTrigger().withIdentity(payload.getName(), payload.getGroup()).usingJobData(CwConstant.PAYLOAD,payload.getDataMap()).withDescription(payload.getDesc()).withSchedule(cronSchedule(payload.getCron())).build();scheduler.scheduleJob(jobDetail,cronTrigger);scheduler.start();log.info("成功创建重复任务!!!");break;}} catch (Exception e) {log.info("job initial failure:{}",e);return APIResult.error(ReturnCodeEnum.JOB_INITIAL_FAILURE);}return APIResult.success(null);}@Overridepublic APIResult getJobList(String name, String groupName) {List
}
2020-12-31 21:58:02.709 INFO 12472 --- [nio-8088-exec-2] c.e.d.service.impl.JobServiceImpl : 成功创建重复任务!!!
{name:'ljl'}
hello world!!!
2020-12-31 21:58:07.706 INFO 12472 --- [eduler_Worker-1] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
2020-12-31 21:58:07.712 DEBUG 12472 --- [eduler_Worker-1] c.e.d.mapper.UserMapper.selectList : ==> Preparing: SELECT id,user_name FROM user
2020-12-31 21:58:07.720 DEBUG 12472 --- [eduler_Worker-1] c.e.d.mapper.UserMapper.selectList : ==> Parameters:
2020-12-31 21:58:07.754 DEBUG 12472 --- [eduler_Worker-1] c.e.d.mapper.UserMapper.selectList : <&#61;&#61; Total: 2
2
{name:&#39;ljl&#39;}
hello world!!!
2020-12-31 21:58:12.008 DEBUG 12472 --- [eduler_Worker-2] c.e.d.mapper.UserMapper.selectList : &#61;&#61;> Preparing: SELECT id,user_name FROM user
2020-12-31 21:58:12.008 DEBUG 12472 --- [eduler_Worker-2] c.e.d.mapper.UserMapper.selectList : &#61;&#61;> Parameters:
2020-12-31 21:58:12.036 DEBUG 12472 --- [eduler_Worker-2] c.e.d.mapper.UserMapper.selectList : <&#61;&#61; Total: 2
2
从日志结果来看&#xff0c;任务执行正常&#xff0c;没有出现空指针异常了。希望采纳&#xff01;