用@Quartz配置启动任务遇到“A component required a bean named 'Myjob1' that could not be found”的问题

先上SpringBoot项目搭建@Quartz系统任务启动流程,报错解决方法在文章末尾

1、新建项目
①新建SpringBoot项目,只需添加Web和Quartz Scheduler依赖
在这里插入图片描述

②使用@EnableScheduling注解开启定时任务
在这里插入图片描述

3、定义Job,方式有两种
①定义一个包含了简单方法的Job,这种定义方式的缺陷就是不能传参
在这里插入图片描述

②定义一个包含参数的Job,继承QuartzJobBean并实现默认方法。
这种方式支持传参,在项目启动时executeInternal() 方法会自动执行

public class Myjob2 extends QuartzJobBean {

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext)
            throws JobExecutionException {
        helloService.sayHello();
    }

    HelloService helloService;

    public HelloService getHelloService() {
        return helloService;
    }
    public void setHelloService(HelloService helloService) {
        this.helloService = helloService;
    }
}

再添加一个服务类,包含简单的方法
在这里插入图片描述

4、自定义一个Quartz配置类,用来配置JobBean和Trigger触发器

/* 在 QuartzConfig 中配置 JobBean 和 Trigger
 *
 * JobBean 的配置有两种方式:
 * 1. 使用 MethodInvokingJobDetailFactoryBean 进行配置
 * 使用 MethodInvokingJobDetailFactoryBean 可以配置目标 Bean 的名字和目标方法的名字,
 * 这种方式不支持传参
 * 2. 使用 JobDetailFactoryBean 进行配置
 * JobDetailFactoryBean 构造出来的 JobBean ,
 * 任务类继承自 QuartzJobBean ,这种方式支持传参,将参数封装在JobDataMap中进行传递
 *
 * Trigger 也有两种方式:SimpleTriggerFactoryBean和CronTriggerFactoryBean
 *
 */
@Configuration
public class QuartzConfig {

    @Bean
    HelloService helloService(){
        return new HelloService();
    }

    @Bean//这种配置job的方式不支持传参
    MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean(){
        MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
        bean.setTargetBeanName("Myjob1");//全部小写,对应Myjob1这个类
        bean.setTargetMethod("sayHello");//对应Myjob1这个类里的sayHello()方法
        return bean;
    }

    @Bean//这种配置job的方式支持传参
    JobDetailFactoryBean jobDetailFactoryBean() {
        JobDetailFactoryBean bean=new JobDetailFactoryBean();
        bean.setJobClass(Myjob2.class);
        JobDataMap map=new JobDataMap();
        map.put("helloService", helloService());
        bean.setJobDataMap(map);
        return bean;
    }

    @Bean//这是简单的触发器,可以自己设置一些内置的参数
    SimpleTriggerFactoryBean simpleTriggerFactoryBean() {
        SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
        bean.setStartTime(new Date());
        bean.setRepeatCount(5);//重复次数5次
        bean.setJobDetail(methodInvokingJobDetailFactoryBean().getObject());
        bean.setRepeatInterval(3000);//间隔时间3秒
        return bean;
    }

    @Bean//使用了cron表达式的触发器
    CronTriggerFactoryBean cronTrigger() {
        CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
        bean.setCronExpression("0/10 * * * * ?");
        bean.setJobDetail(jobDetailFactoryBean().getObject());
        return bean;
    }

    @Bean//在这里安排上之前已经搞好的两个触发器
    SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        //bean.setJobDetails(methodInvokingJobDetailFactoryBean().getObject(),jobDetailFactoryBean().getObject());
        bean.setTriggers(cronTrigger().getObject(), simpleTriggerFactoryBean().getObject());
        return bean;
    }
}

5、最后启动QuartzApplication测试,会发现报如下错误:

Description:
A component required a bean named ‘Myjob1’ that could not be found.
Action:
Consider defining a bean named ‘Myjob1’ in your configuration.

说是 Myjob1 这个bean没有找到,但是我之前明明用@Component注册过Myjob1这个类。

解决办法:
方法一:给@Component注解加入value=“Myjob1”属性,这样就不怕找不到了
在这里插入图片描述

方法二:把QuartzConfig里的bean.setTargetBeanName()里的Bean名称换成小写就好了。
在这里插入图片描述

最后系统启动任务就能正常运行了:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43724369/article/details/89323691