小编典典

无法在组件中注入bean

spring-boot

我已经使用此链接实现了Spring Quartz调度程序示例,
我有一个简单的MyJobTwo.java组件,该组件具有executeInternal()使用调用的方法CronTriggerFactoryBean

这是我的 QuartzConfiguration.java

@Configuration 
@ComponentScan("com.example") 
public class QuartzConfiguration {
    // we need to create a bean that will excuted by MethodInvokingJobDetailFactoryBean
    // in this case we have myJobOne is the simple bean

    @Bean
    public MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean() {
        MethodInvokingJobDetailFactoryBean obj = new MethodInvokingJobDetailFactoryBean();
        obj.setTargetBeanName("myJobOne");
        obj.setTargetMethod("myTask");
        return obj;
    }

    // This trigger will schedule the job after 3 seconds and repeat after every 30 seconds for 3+1 times.
    @Bean
    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(){
        SimpleTriggerFactoryBean stFactory = new SimpleTriggerFactoryBean();
       stFactory.setJobDetail(methodInvokingJobDetailFactoryBean().getObject());
        stFactory.setStartDelay(3000);
        stFactory.setRepeatInterval(30000);
        stFactory.setRepeatCount(1);
        return stFactory;
    }

    // We use it to configure complex job such as job scheduling using cron-expression
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean(){
        JobDetailFactoryBean factory = new JobDetailFactoryBean();
        factory.setJobClass(MyJobTwo.class);
        // Map<String,Object> map = new HashMap<String,Object>();
        // map.put("myJobOne", myJobOne);
        // map.put(MyJobTwo.myJodOne, 1);
        //factory.setJobDataAsMap(map);
        //factory.setGroup("mygroup");
        //factory.setName("myjob");
        return factory;
    }

    // CronTriggerFactoryBean configures JobDetailFactoryBean
    // We also configure start delay, trigger name, and cron-expression to schedule the job

    @Bean
    public CronTriggerFactoryBean cronTriggerFactoryBean(){
        CronTriggerFactoryBean stFactory = new CronTriggerFactoryBean();
        stFactory.setJobDetail(jobDetailFactoryBean().getObject());
        stFactory.setStartDelay(3000);
        //stFactory.setName("mytrigger");
        //stFactory.setGroup("mygroup");
        stFactory.setCronExpression("0 0/1 * 1/1 * ? *");
        return stFactory;
    }

    // SchedulerFactoryBean use to register the triggers 
    // those registered triggers will be executed
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean scheduler = new SchedulerFactoryBean();
        scheduler.setTriggers(cronTriggerFactoryBean().getObject());
        //scheduler.setTriggers(simpleTriggerFactoryBean().getObject());
        return scheduler;
    }
}

这是我使用CronTriggerFactoryBean执行的bean。

MyJobTwo.java

@Component
public class MyJobTwo extends QuartzJobBean {

    private SmtpMailSender smtpMailSender;

    @Autowired
    public MyJobTwo(MyJobOne myJobOne, SmtpMailSender smtpMailSender) {
        super();
        this.myJobOne = myJobOne;
        this.smtpMailSender = smtpMailSender;
    }

    @Override
    protected void executeInternal(JobExecutionContext ctx)
            throws JobExecutionException {
        System.out.println("this is the test");
        myJobOne.myTask();
        System.out.println("task is done");
    }

}

每当我尝试注入其他bean和服务时,都会出现这些错误。任何人都知道导致这些错误的原因是什么,我需要进行哪些更改?

org.quartz.SchedulerException: Job instantiation failed
    at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:45)
    at org.quartz.core.JobRunShell.initialize(JobRunShell.java:127)
    at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:375)
Caused by: java.lang.InstantiationException: com.example.job.MyJobTwo
    at java.lang.Class.newInstance(Class.java:427)
    at org.springframework.scheduling.quartz.AdaptableJobFactory.createJobInstance(AdaptableJobFactory.java:58)
    at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:41)
    ... 2 common frames omitted
Caused by: java.lang.NoSuchMethodException: com.example.job.MyJobTwo.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.newInstance(Class.java:412)
    ... 4 common frames omitted

阅读 427

收藏
2020-05-30

共1个答案

小编典典

默认的Job Factory实现AdaptableJobFactory不具有自动装配功能。
要使用依赖注入,请执行以下操作:

1.创建工作工厂

package com.concretepage.config;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
    private transient AutowireCapableBeanFactory beanFactory;

    public void setApplicationContext(final ApplicationContext context) {
        beanFactory = context.getAutowireCapableBeanFactory();
    }

    @Override
    public Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
        final Object job = super.createJobInstance(bundle);
        beanFactory.autowireBean(job);  //the magic is done here
        return job;
    }
}

可以在http://codrspace.com/Khovansa/spring-quartz-with-a-
database/找到实现

2,更新QuartzConfiguration中的schedulerFactoryBean声明:

@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
    SchedulerFactoryBean scheduler = new SchedulerFactoryBean();
    scheduler.setTriggers(simpleTriggerFactoryBean().getObject(), cronTriggerFactoryBean().getObject());
    scheduler.setJobFactory(jobFactory());
    return scheduler;
}

@Bean
public JobFactory jobFactory() {
    return new AutowiringSpringBeanJobFactory();
}
  1. 使用基于setter的注入而不是构造函数注入
2020-05-30