版权声明:标明出处自由转载 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