SpringBoot+Quartz定时任务:Job类对象注入(Demo)

版权声明:标明出处自由转载 https://blog.csdn.net/qq_36226997/article/details/91468887

接上文
SpringBoot+Quartz定时框架(Demo)

1.自定类

public class UserService {
    public void testMethod(){
        System.out.println("UserService.testMethod");
    }
}

2.定时任务类中调用测试方法

import com.example.demo.pojo.UserService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;

/**
 * 定时任务类
 */
public class QuartzDemo implements Job {
    //注入自定类
    @Autowired
    private UserService userService;
    
    /**
     * 任务被触发时所执行的方法
     * @param context
     * @throws JobExecutionException
     */
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        //调用自定类测试方法
        this.userService.testMethod();
    }
}

3.控制台报错

java.lang.NullPointerException: null
	at com.example.demo.quartz.QuartzDemo.execute(QuartzDemo.java:25) ~[classes/:na]
	at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.2.1.jar:na]
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.2.1.jar:na]

由报错可知UserService对象未注入,查看源码得知

//1.创建job对象
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean() {
        JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
        //关联Job类
        factoryBean.setJobClass(QuartzDemo.class);//<------这行是重点(敲黑板)
        return factoryBean;
    }

设置Job类的底层原理是反射,并没有经过spring的自动注入,所以UserService为null

4.解决办法

4.1 编写一个MyAdaptableJobFactory类

手动将UserService对象加入SpringIOC容器
编写一个MyAdaptableJobFactory类解决实现该操作

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;

@Component("myAdaptableJobFactory")
public class MyAdaptableJobFactory extends AdaptableJobFactory {
    //AutowireCapableBeanFactory 可以将一个对象添加到SpringIOC容器中,并且完成该对象注入
    @Autowired
    private AutowireCapableBeanFactory autowireCapableBeanFactory;

    /**
     * 该方法需要将实例化的任务对象手动的添加到SpringIOC容器中并且完成对象的注入
     */
    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        Object object = super.createJobInstance(bundle);
        //将object对象添加到SpringIOC容器中,并完成注入
        this.autowireCapableBeanFactory.autowireBean(object);
        return object;
    }
}

4.2 设置新的JobFactory

//3.创建Scheduled对象
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean,MyAdaptableJobFactory myAdaptableJobFactory) {
        SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
        //关联Trigger
        factoryBean.setTriggers(cronTriggerFactoryBean.getObject());
        //设置新的JobFactory
        factoryBean.setJobFactory(myAdaptableJobFactory);
        return factoryBean;
    }

若控制台报错

org.quartz.SchedulerException: Job instantiation failed
	at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:47) ~[spring-context-support-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.quartz.core.JobRunShell.initialize(JobRunShell.java:127) ~[quartz-2.2.1.jar:na]
	at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:375) [quartz-2.2.1.jar:na]
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.demo.quartz.QuartzDemo': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo.pojo.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBean(AbstractAutowireCapableBeanFactory.java:316) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at com.example.demo.config.MyAdaptableJobFactory.createJobInstance(MyAdaptableJobFactory.java:22) ~[classes/:na]
	at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:43) ~[spring-context-support-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	... 2 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo.pojo.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1655) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1214) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1168) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	... 8 common frames omitted

则在UserService类上加@Component注解

import org.springframework.stereotype.Component;

@Component
public class UserService {

    public void testMethod(){
        System.out.println("UserService.testMethod");
    }
}

控制台正确输出

UserService.testMethod
UserService.testMethod
UserService.testMethod
UserService.testMethod
UserService.testMethod
UserService.testMethod
UserService.testMethod

猜你喜欢

转载自blog.csdn.net/qq_36226997/article/details/91468887
今日推荐