Spring 无法在实现 Quartz Job 的 class 中注入 Bean
Spring cannot inject Bean in class that implements Quartz Job
我正在尝试从实现 Quartz Job 的 class 发送一封电子邮件,为此我必须在 class 中@Autowire IEmailService。
这是我用来创建 Quartz Job 的方法:
@Override
public Boolean sendInfoEmail(ManifestationProp manifProp, ServletRequest request) throws SchedulerException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String token = httpRequest.getHeader("jwt_token");
if(token == null) {
System.out.println("(ManifestationPropDaoImp) - TOKEN NULL");
return false;
}
String email = tokenUtils.getUsernameFromToken(token);
User user = userDao.findUserByEmail(email);
if(update(manifProp) != null) {
Scheduler sc = StdSchedulerFactory.getDefaultScheduler();
sc.start();
JobKey jobKey = new JobKey("Job_"+manifProp.getId(),"group1");
if(!sc.checkExists(jobKey)) { System.out.println("-----------------------------------------------");
System.out.println("Scheduling a Job for Manifestation Prop with ID - "+ manifProp.getId());
System.out.println("Current time - " + new Date());
System.out.println("Scheduled time - NOW" );
System.out.println("User - "+ user.getEmail());
System.out.println("Manifestation Prop - "+manifProp.getName());
JobDataMap jdm = new JobDataMap();
jdm.put("manifProp",manifProp);
jdm.put("user", user);
JobDetail jobDetail = JobBuilder.newJob(QuartzInformUser.class)
.withIdentity(jobKey)
.usingJobData(jdm)
.build();
Trigger t = TriggerBuilder.newTrigger().withIdentity("SimpleTrigger_"+manifProp.getId()).startNow().build();
sc.scheduleJob(jobDetail, t);
System.out.println("-----------------------------------------------");
}else {
System.out.println(" *** Job_"+manifProp.getId()+" already exists! *** ");
}
return true;
}else {
System.out.println("Could not update manifestation prop!");
}
return false;
}
这里是class实现Job接口的代码:
@Service
public class QuartzInformUser implements Job{
@Autowired
IEmailService emailService;
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
try {
JobDataMap dataMap = arg0.getJobDetail().getJobDataMap();
User user = (User)dataMap.get("user");
ManifestationProp manifProp = (ManifestationProp)dataMap.get("manifProp");
System.out.println("USER: "+user);
System.out.println("MANIFESTATION PROP: "+manifProp);
emailService.informUser(user,manifProp);
}catch(Exception e){
e.printStackTrace();
}
}
}
Quartz Job 创建得很好,问题出在 class QuartzInformUser
。 Spring 不会将 IEmailService
注入 class,因此字段 emailService
是 null
,我得到以下异常:
如果有人知道我该如何解决这个问题,我将不胜感激!提前致谢!
您是否在项目中添加了 AutowiringSpringBeanJobFactory
?这将为 quartz 作业添加自动装配的支持。
public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private transient AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
beanFactory = applicationContext.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}
您还需要创建一个 jobFactory 并将应用程序上下文设置为您的 quartz 作业。这应该在 @Configuration
class
@Bean
public JobFactory jobFactory(ApplicationContext applicationContext)
{
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
(只需将此 class 复制并粘贴到您的项目中)
您将要使用各种 Quartz 组件的 spring helpers/implementations,这样您创建的作业将由 spring 管理。
- https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#scheduling-quartz
- http://www.baeldung.com/spring-quartz-schedule
... 是两个很好的起点(尽管您需要确保您查看的文档适用于您正在使用的 spring 版本;spring-boot例如有 scheduling/quartz)
的开胃菜
我正在尝试从实现 Quartz Job 的 class 发送一封电子邮件,为此我必须在 class 中@Autowire IEmailService。
这是我用来创建 Quartz Job 的方法:
@Override
public Boolean sendInfoEmail(ManifestationProp manifProp, ServletRequest request) throws SchedulerException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String token = httpRequest.getHeader("jwt_token");
if(token == null) {
System.out.println("(ManifestationPropDaoImp) - TOKEN NULL");
return false;
}
String email = tokenUtils.getUsernameFromToken(token);
User user = userDao.findUserByEmail(email);
if(update(manifProp) != null) {
Scheduler sc = StdSchedulerFactory.getDefaultScheduler();
sc.start();
JobKey jobKey = new JobKey("Job_"+manifProp.getId(),"group1");
if(!sc.checkExists(jobKey)) { System.out.println("-----------------------------------------------");
System.out.println("Scheduling a Job for Manifestation Prop with ID - "+ manifProp.getId());
System.out.println("Current time - " + new Date());
System.out.println("Scheduled time - NOW" );
System.out.println("User - "+ user.getEmail());
System.out.println("Manifestation Prop - "+manifProp.getName());
JobDataMap jdm = new JobDataMap();
jdm.put("manifProp",manifProp);
jdm.put("user", user);
JobDetail jobDetail = JobBuilder.newJob(QuartzInformUser.class)
.withIdentity(jobKey)
.usingJobData(jdm)
.build();
Trigger t = TriggerBuilder.newTrigger().withIdentity("SimpleTrigger_"+manifProp.getId()).startNow().build();
sc.scheduleJob(jobDetail, t);
System.out.println("-----------------------------------------------");
}else {
System.out.println(" *** Job_"+manifProp.getId()+" already exists! *** ");
}
return true;
}else {
System.out.println("Could not update manifestation prop!");
}
return false;
}
这里是class实现Job接口的代码:
@Service
public class QuartzInformUser implements Job{
@Autowired
IEmailService emailService;
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
try {
JobDataMap dataMap = arg0.getJobDetail().getJobDataMap();
User user = (User)dataMap.get("user");
ManifestationProp manifProp = (ManifestationProp)dataMap.get("manifProp");
System.out.println("USER: "+user);
System.out.println("MANIFESTATION PROP: "+manifProp);
emailService.informUser(user,manifProp);
}catch(Exception e){
e.printStackTrace();
}
}
}
Quartz Job 创建得很好,问题出在 class QuartzInformUser
。 Spring 不会将 IEmailService
注入 class,因此字段 emailService
是 null
,我得到以下异常:
如果有人知道我该如何解决这个问题,我将不胜感激!提前致谢!
您是否在项目中添加了 AutowiringSpringBeanJobFactory
?这将为 quartz 作业添加自动装配的支持。
public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private transient AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
beanFactory = applicationContext.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}
您还需要创建一个 jobFactory 并将应用程序上下文设置为您的 quartz 作业。这应该在 @Configuration
class
@Bean
public JobFactory jobFactory(ApplicationContext applicationContext)
{
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
(只需将此 class 复制并粘贴到您的项目中)
您将要使用各种 Quartz 组件的 spring helpers/implementations,这样您创建的作业将由 spring 管理。
- https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#scheduling-quartz
- http://www.baeldung.com/spring-quartz-schedule
... 是两个很好的起点(尽管您需要确保您查看的文档适用于您正在使用的 spring 版本;spring-boot例如有 scheduling/quartz)
的开胃菜