java - 无法在组件中注入(inject) bean

标签 java spring spring-mvc spring-boot

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

这是我的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");
    }

}

每当我尝试注入(inject)其他 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

最佳答案

默认的作业工厂实现AdaptableJobFactory没有 Autowiring 功能。
要使用依赖注入(inject),请执行以下操作:

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();
}
  • 使用基于 setter 的注入(inject)而不是构造函数注入(inject)
  • 关于java - 无法在组件中注入(inject) bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33651601/

    相关文章:

    java - 整数结果与计算不同

    java - 在 @RequestMapping 的值中使用或不使用前导斜线。需要官方文档或指向 Spring 源代码?

    java - 如何编写一个cron表达式或设置一个在Spring中只执行一次的计时器?

    eclipse - 创建带有注释且无 xml 文件的 Spring 4 MVC 项目

    spring - TomEE :- Caused by: java. lang.RuntimeException at org.apache.xbean.asm5.MethodVisitor.visitTypeAnnotation(来源未知)

    java - DataOutputStream write( int i ) 和 writeByte( int i ) 有什么区别

    java - SpringJunit4ClassRunner——我可以改变注入(inject)资源的生命周期吗?

    java - 如何将 JavaScript 变量发送到 Java 小程序

    java - 在spring bean中处理xml配置文档

    java - 从 Web 应用程序访问静态文件(webapp/static/例如)