Spring不能在实现Quartz Job的类中注入Bean

时间:2018-04-16 13:37:21

标签: java spring spring-boot quartz-scheduler

我正在尝试从实现Quartz Job的类发送电子邮件,为了做到这一点,我必须@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;
    }

以下是实现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创建得非常好,问题出在班级QuartzInformUser。 Spring不会将IEmailService注入到类中,因此字段emailServicenull并且我得到以下异常:

enter image description here

如果有人知道如何解决这个问题我真的很感激帮助!提前谢谢!

2 个答案:

答案 0 :(得分:1)

您将需要使用各种Quartz组件的spring helpers / implementation,以便您创建的作业将由spring管理。

...是两个很好的起点(尽管你需要确保你看到的文档适合你正在使用的弹簧版本;例如spring-boot有一个用于调度/石英的启动器)

答案 1 :(得分:0)

您是否在项目中添加了AutowiringSpringBeanJobFactory?这将增加自动装配对石英作业的支持。

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

 @Bean
 public JobFactory jobFactory(ApplicationContext applicationContext)
 {
     AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
     jobFactory.setApplicationContext(applicationContext);
     return jobFactory;
 }

(只需在项目中复制并粘贴此类)