美文网首页
Spring-boot 集成 quartz 时无法注入bean

Spring-boot 集成 quartz 时无法注入bean

作者: 桃子家的二哈 | 来源:发表于2021-01-21 00:01 被阅读0次

今天在调试quartz(基于内存实现的定时任务)代码时,发现无法@Autowired注入bean服务

业务场景

需要定时同步钉钉组织以及人员信息,每天凌晨等BI抽取完成后进行,预计每天凌晨5点。

发现问题

代码如下:

/**
 * @author: create by AdoreFT
 * @version: v1.0
 * @keyWord: Time is not waiting for me, you forgot to take me away.
 * @description: DingTalkOrgTask
 * @Date: 1/14/21 4:20 PM
 **/
@DisallowConcurrentExecution
public class DingTalkOrgTask extends QuartzJobBean {
    private static final Logger logger = LoggerFactory.getLogger(DingTalkOrgTask.class);

    @Autowired
    private DingTalkGetUsrInfomationService usrInfomationService;

    @Autowired
    private DingTalkGetOrgService orgService;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //耗时监控
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        try {
            //组织同步
            orgService.uploadOrgToDD();
            //人员同步
            usrInfomationService.uploadUserToDD();
        } catch (Exception e) {
            logger.info(String.format("组织以及人员同步失败:%s MS", stopWatch.getTime()));
        }finally {
            stopWatch.stop();
        }
        logger.info(String.format("组织人员同步耗时总时间:%s MS", stopWatch.getTime()));
    }
}

就如上代码所示:在继承QuartzJobBean来实现业务时,@Autowired无法注入到服务上,导致null空指针
通过网上查询原来:Spring容器可以管理Bean,但是Quartz的job是自己管理的,如果在Job中注入Spring管理的Bean,需要先把Quartz的Job也让Spring管理起来。

管理Quartz job Bean

通过自定义JobFactory,通过spring的AutowireCapableBeanFactory进行注入。

  • AutowireCapableBeanFactory

它的功能主要是为了装配applicationContext管理之外的Bean。

  • 自定义JobFactory
    代码如下:
/**
 * @author: create by AdoreFT
 * @version: v1.0
 * @keyWord: Time is not waiting for me, you forgot to take me away.
 * @description: UhiJobFactory
 * @Date: 1/21/21 4:30 PM
 **/
@Component
public class UhiJobFactory extends SpringBeanJobFactory {

    @Autowired
    private AutowireCapableBeanFactory beanFactory;

    /**
     * 这里覆盖了super的createJobInstance方法,对其创建出来的类再进行autowire。
     */
    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        Object jobInstance = super.createJobInstance(bundle);
        beanFactory.autowireBean(jobInstance);
        return jobInstance;

    }
}

注意:此方法要由Spring管理 添加:@Component注解。

在QuartzConfig中引入 UhiJobFactory

代码实现如下:

/**
 * @author: create by AdoreFT
 * @version: v1.0
 * @keyWord: Time is not waiting for me, you forgot to take me away.
 * @description: QuartzConfig
 * @Date: 1/13/21 3:31 PM
 **/
@Configuration
public class QuartzConfig {

    @Value("${cron.org_key}")
    private String cronOrg;

    @Autowired
    private UhiJobFactory uhiJobFactory;

    @Bean
    public JobDetailFactoryBean jobOrgDetailFactoryBean(){
        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
        jobDetailFactoryBean.setJobClass(DingTalkOrgTask.class);
        return jobDetailFactoryBean;
    }

    /**
     * 使用触发器
     * cron(每天凌晨2点跑一次)
     * */
    @Bean
    public CronTriggerFactoryBean cronOrgTriggerFactoryBean() {
        CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
        cronTriggerFactoryBean.setJobDetail(jobOrgDetailFactoryBean().getObject());
        cronTriggerFactoryBean.setCronExpression(cronOrg);
        return cronTriggerFactoryBean;
    }

    @Bean
    public SchedulerFactoryBean schedulerOrgFactoryBean(){
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setTriggers(cronOrgTriggerFactoryBean().getObject());
        schedulerFactoryBean.setJobFactory(uhiJobFactory);
        return schedulerFactoryBean;
    }

    @Bean(name="Scheduler")
    public Scheduler schedulerOrg() {
        return schedulerOrgFactoryBean().getScheduler();
    }
}

如上代码:只需要在 schedulerFactoryBean.setJobFactory(uhiJobFactory);就可以。

SpringMVC 方式 需要在触发器中配置该JobFactory

<property name="jobFactory">
      <bean class="com.uhi.applyment4sub.factory.UhiJobFactory" />
</property>

相关文章

网友评论

      本文标题:Spring-boot 集成 quartz 时无法注入bean

      本文链接:https://www.haomeiwen.com/subject/mirdzktx.html