java手动触发定时任务资源不注入问题

我们采用的定时是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 getBean(Class 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();
        } 
    }

我在网上看到还有其他一种解决定时报空指针的方法,可能是因为其他的一些配置不同,所以我的项目中使用没有效果,但是可以参考下:

  1. 成员变量添加注解@Autowired

  2. 然后在方法中(如例子中的excute方法)添加以下代码,自动注入成员变量实现类

    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

 

你可能感兴趣的:(java,springBoot)