SpringBoot Quartz 优雅解决Job注入为空

看了网上很多方案,大多都是实现重载 AdaptableJobFactory,然后利用factory.autowireBean()来注入,我在本地实验,可能版本原因,找不到AdaptableJobFactory类,另辟蹊径,实现了这一版。

一.自实现JobFactory接口MyJobFactory,代码从系统原生SimpleJobFactory拿来,只修改其中一行:

将 return jobClass.newInstance() 改为:

return (Job) SpringContextUtils.getBean(jobClass);

可以看出,默认是newInstance()的,自然无法使用spring注入,修改为从SpringContextUtils里获取就可以达到目的


package com.alimama.qa.platform.makaira.taskScheduler;

import com.alimama.qa.platform.utils.SpringContextUtils;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @program makaira
 * @description:
 * @author: xiaopeng.sxp
 * @create: 2019/05/06 10:22
 */

public class MyJobFactory implements JobFactory {

    private final Logger log = LoggerFactory.getLogger(getClass());

    protected Logger getLog() {
        return log;
    }

    public Job newJob(TriggerFiredBundle bundle, Scheduler Scheduler) throws SchedulerException {

        JobDetail jobDetail = bundle.getJobDetail();
        Class<? extends Job> jobClass = jobDetail.getJobClass();
        try {
            if (log.isDebugEnabled()) {
                log.debug(
                        "Producing instance of Job '" + jobDetail.getKey() +
                                "', class=" + jobClass.getName());
            }

            return (Job) SpringContextUtils.getBean(jobClass);
//            return jobClass.newInstance();
        } catch (Exception e) {
            SchedulerException se = new SchedulerException(
                    "Problem instantiating class '"
                            + jobDetail.getJobClass().getName() + "'", e);
            throw se;
        }
    }

}

@Component
public class SpringContextUtils implements ApplicationContextAware {

    public static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        SpringContextUtils.applicationContext = applicationContext;
    }

    public static Object getBean(String name) {
        return applicationContext.getBean(name);
    }

    public static Object getBean(Class className) {
        return applicationContext.getBean(className);
    }


    public static <T> T getBean(String name, Class<T> requiredType) {
        return applicationContext.getBean(name, requiredType);
    }

    public static boolean containsBean(String name) {
        return applicationContext.containsBean(name);
    }

    public static boolean isSingleton(String name) {
        return applicationContext.isSingleton(name);
    }

    public static Class<? extends Object> getType(String name) {
        return applicationContext.getType(name);
    }

}

二. 使自定义jobFactory替代系统默认实现

跟踪源代码,发现可以在quartz配置文件里指定 jobFactoryClass ,

在系统resource目录里添加quartz.properties文件,可以从jar包里copy一份 ,添加一句:


org.quartz.scheduler.jobFactory.class: com.alimama.qa.platform.makaira.taskScheduler.MyJobFactory

# Customized Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#

org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false

org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 100
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true

org.quartz.jobStore.misfireThreshold: 60000

org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore

org.quartz.scheduler.jobFactory.class: com.alimama.qa.platform.makaira.taskScheduler.MyJobFactory

三. 重启应用,设置断点,看到job里的service已经被注入了

你可能感兴趣的:(SpringBoot Quartz 优雅解决Job注入为空)