我们采用的定时是springboot+Job定时:
@Component public class TransferJob implements Job { Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired @Qualifier(value = "remoteRestTemplate") private RestTemplate restTemplate; @Resource protected BeanMapper beanMapper; @Autowired private BeanFactory beanFactory; @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { ApplicationContext applicationContext = GetBeanUtil.getApplicationContext(); //如果Spring中无法去到bean的话,调用下面的方法取bean if (restTemplate==null){ restTemplate = (RestTemplate) GetBeanUtil.getBean("remoteRestTemplate"); } if (beanMapper==null){ beanMapper= (BeanMapper ) GetBeanUtil.getBean("beanMapper"); } if(beanFactory==null){ //获取beanfactory beanFactory = applicationContext.getAutowireCapableBeanFactory(); } //获取job任务ID String taskId = jobExecutionContext.getMergedJobDataMap().getString("taskId"); String instanceId = jobExecutionContext.getJobDetail().getJobDataMap().getString("instanceId"); //业务代码 ..... } } GetBeanUtil: import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class GetBeanUtil implements ApplicationContextAware { protected static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { context = applicationContext; } public static Object getBean(String name) { return context.getBean(name);//name表示其他要注入的注解name名 } public static <T> T getBean(Class<T> c) { return context.getBean(c);//T表示类 } public static ApplicationContext getApplicationContext(){ return context; } }
//手动触发定时任务的方法
//触发定时任务 public void triggerTransferJob(String taskId){ logger.error("启动订阅任务,触发定时任务__________________"+taskId); Scheduler scheduler =null; JobKey jobKey =null; try { scheduler = schedulerFactory.getScheduler(); jobKey = new JobKey("trigger_"+taskId,"r-trigger"); JobDetail jobDetail = JobBuilder.newJob(TransferJob.class).withIdentity(jobKey).build(); JobDataMap jobDataMap = jobDetail.getJobDataMap(); jobDataMap.put("taskId", taskId); Trigger trigger = TriggerBuilder.newTrigger() // .withIdentity("trigger_"+taskId , "r-trigger") .startAt(new Date(System.currentTimeMillis() + 180000)) .build(); scheduler.scheduleJob(jobDetail , trigger); // JobExecutionContextImpl jobExecutionContext = new JobExecutionContextImpl(scheduler, (TriggerFiredBundle) trigger,transferJob); // transferJob.execute(jobExecutionContext); // 启动 if (!scheduler.isShutdown()){ scheduler.start(); }else{ Thread.sleep(5000); // 删除job scheduler.deleteJob(jobKey); } } catch (Exception e) { e.printStackTrace(); // throw new RuntimeException(); } }
我在网上看到还有其他一种解决定时报空指针的方法,可能是因为其他的一些配置不同,所以我的项目中使用没有效果,但是可以参考下:
-
成员变量添加注解@Autowired
-
然后在方法中(如例子中的excute方法)添加以下代码,自动注入成员变量实现类
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);