- SchedulerConfig.java定时任务Job中service注入NullPointerException
[原因]:trigger没有注册,很诡异?没设置时间也运行? - 定时任务Job中service注入
NullPointerException
[原因]:创建的Service是Quartz管理的,不是Spring,无法注入
Job 是通过反射出来的实例,不受spring的管理
@Autowired
private ApplicationContext applicationContext;
@Bean(name = "scheduler")
public SchedulerFactoryBean schedulerFactoryBean(Trigger trigger) {
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
// 用于quartz集群,QuartzScheduler启动时更新已存在的job
factoryBean.setOverwriteExistingJobs(true);
// 延时启动,应用启动1秒后
factoryBean.setStartupDelay(1);
// 注册触发器
factoryBean.setTriggers(trigger);
// Spring依赖注入为null
SpringQuartzJobFactory jobFactory = new SpringQuartzJobFactory();
jobFactory.setApplicationContext(applicationContext);
factoryBean.setJobFactory(jobFactory);
return factoryBean;
}
- 多个任务怎么办?
解决@Autowired空指针Null问题,即依赖注入的属性为null
- 创建
SpringQuartzJobFactory.java
- 期间用到
applicationContext
@Component("springQuartzJobFactory")
public class SpringQuartzJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
@Autowired
private AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(final ApplicationContext context) throws BeansException {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object obj = super.createJobInstance(bundle);
beanFactory.autowireBean(obj);
return obj;
}
}
/*
主要思路是通过新建一个AutowiringSpringBeanJobFactory 实现 quartz 的SpringBeanJobFactory(job生产工厂类)
通过实现ApplicationContextAware接口 set ApplicationContextAware(上下文)到该新建job工厂类。
然后通过super.createJobInstance(bundle) 创建 job, beanFactory来autowired job实例
*/
参考资料
- spring boot quartz scheduler example code using maven
- Quartz (2.1.6) java config with spring (3.2.1). Using a SpringBeanJobFactory to automatically autowire quartz classes.
- 《SpringBoot整合Quartz实现定时任务》
- 定时任务quartz的job中注入spring bean时null的问题 / zhongruitech.com
- springboot整合quartz配置多任务 - 未完成的空间 - CSDN博客
- quartz里job不执行的解决方案(并发量太低原因) - 一名普通码农的菜地 - CSDN博客
SpringBoot + Quartz
@Bean(name = "psBnAbsNoticeJobDetail")
public JobDetailFactoryBean psBnAbsNoticeJobDetail()
{
JobDetailFactoryBean psBnAbsNoticeFactory = new JobDetailFactoryBean();
psBnAbsNoticeFactory.setJobClass(PsBnAbsNoticeTask.class);
psBnAbsNoticeFactory.setName("PsBnAbsNoticeTask");
psBnAbsNoticeFactory.setDescription("push abnormal attendance notice");
psBnAbsNoticeFactory.setDurability(true);
return psBnAbsNoticeFactory;
}
/**
* 每天早上5点推送异常打卡记录(秒 分 时 日 月 星期几)
* jobDtail和trigger是一一对应
*/
@Bean(name = "psBnAbsNoticeJobTrigger")
public CronTriggerFactoryBean psBnAbsNoticeJobTrigger(@Qualifier("psBnAbsNoticeJobDetail") JobDetail job)
{
CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
trigger.setJobDetail(job);
trigger.setCronExpression("0 */1 * * * ?");
return trigger;
}
- 定时任务
/*
* 异常打卡记录推送
*/
@PersistJobDataAfterExecution
public class PsBnAbsNoticeTask extends QuartzJobBean {
private static final Logger logger = LoggerFactory.getLogger(PsBnAbsNoticeTask.class);
@Autowired
PsBnAbsDetailedService psbnAbsDetailedService;
@Autowired
HrConfig hrConfig;
@Override
protected void executeInternal(JobExecutionContext context) {
logger.info("开始定时任务 --- PsBnAbsNoticeTask --- " + new Date());
// 凌晨推送,获取昨天日期
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE,-1);
Date time = calendar.getTime();
String yesterday = new SimpleDateFormat("yyyy-MM-dd").format(time);
List<PsBnAbsDetailedEntity> entityList = psbnAbsDetailedService.getPsBnAbsNoticeDetailed(yesterday);
for (PsBnAbsDetailedEntity entity: entityList) {
if (entity.getEmpLid()== null) {
continue;
}
pushPsBnAbsNotice(entity);
}
logger.info("结束定时任务 --- PsBnAbsNoticeTask --- " + new Date());
}
private void pushPsBnAbsNotice(PsBnAbsDetailedEntity entity) {
Map<String, Object> param = new HashMap<>();
param.put("from", "考勤异常");
param.put("to", entity.getEmpLid());
param.put("type", 80);
param.put("source", "bpm");
Map<String, String> content = new HashMap<>();
String detail = "";
if (entity.getBnAmAbstype().equals("2")) {
detail += "早班卡:未打卡\n";
}
if (entity.getBnNmAbstype().equals("2")) {
detail += "中班卡:未打卡\n";
}
if (entity.getBnPmAbstype().equals("2")) {
detail += "下班卡:未打卡\n";
}
String qhAbsDate = DateUtil.toStandardDateStr(entity.getQhAbsDate());
content.put("title", "考勤异常提醒("+qhAbsDate+")");
String substance = "您的考勤存在异常,请及时处理!\n打卡号:"+entity.getEmpLid()+"\n"+detail+"打卡日期:"+qhAbsDate;
content.put("substance", substance);
param.put("content", content);
// 推送公众号消息
String reqStr = JSONObject.toJSONString(param);
String url = hrConfig.getMoaApiSendMsg();
doPostJson(url, reqStr);
}
}
网友评论