Spring boot 无法自动连接JobLauncher,始终返回null

Spring boot 无法自动连接JobLauncher,始终返回null,spring-boot,spring-batch,job-scheduling,Spring Boot,Spring Batch,Job Scheduling,我尝试将每个作业链接到一个线程,以便可以使用不同的cron值同时启动多个作业,但jobLauncher始终为null 我试图在Configuation类中将jobLauncher创建为一个bean,但它从未起作用 @Component public class MyTask extends Thread { @Autowired private ApplicationContext context; @Autowired private JobLauncher job

我尝试将每个作业链接到一个线程,以便可以使用不同的cron值同时启动多个作业,但jobLauncher始终为null

我试图在Configuation类中将jobLauncher创建为一个bean,但它从未起作用

@Component
public class MyTask extends Thread {

   @Autowired
   private ApplicationContext context;

   @Autowired
   private JobLauncher jobLauncher;

   @Autowired
   private Batchconfig config;


   public void run() {
     Jobs job = Scheduler.listLinked.get(this);
     if (job != null && job.isState()) {
        JobParameters jobParameters = new JobParametersBuilder().addLong("time", System.currentTimeMillis())
                .addString("param", job.getParam()).toJobParameters();
        try {
            JobExecution jobExecution = jobLauncher.run(config.execute(job.getName()), jobParameters);
            System.out.println("Job's Status:::" + jobExecution.getStatus());
        } catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException
                | JobParametersInvalidException e) {
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
  }

}

@Component
public class Scheduler implements SchedulingConfigurer {


   @Override
   public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
     set();
     for (Jobs j : list) {
        MyTask th = new MyTask();
        listLinkedInverse.put(j, th);
        listLinked.put(th, j);
        taskRegistrar.addCronTask(th, j.getCron());
     }
   }

}
例外情况:

java.lang.NullPointerException
   at com.generator.config.batch.scheduler.MyTask.run(MyTask.java:39)
   at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
   at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93)
   at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
   at java.util.concurrent.FutureTask.run(Unknown Source)
   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
   at java.lang.Thread.run(Unknown Source)

MyTask
实例是手动创建的(在
MyTask th=new MyTask()
中),而不是由Spring创建的,因此不会执行依赖项注入,并且自动连线的
JobLauncher
将为空

您需要创建一个类型为
MyTask
(以便正确注入其依赖项)的bean,然后将其作为协作者注入到
调度程序
类中

作为旁注,这不是同时启动多个作业的理想方式。您正在为每个线程创建一个
JobLauncher
,默认情况下,它反过来使用一个
SyncTaskExecutor
。您可以做的是创建一个
JobLauncher
,并使用线程池对其进行配置,以同时启动作业,例如:

@Bean
public JobLauncher jobLauncher() {
   SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
   jobLauncher.setJobRepository(jobRepository());
   jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor()); // or use ThreadPoolTaskExecutor
   jobLauncher.afterPropertiesSet();
   return jobLauncher;
}

您可以在参考文档的一节中找到更多详细信息。

我尝试了这个解决方案,它成功了

@Component
public class Scheduler {
        @Autowired
private ApplicationContext context;


@Autowired
public static JobLauncher jobLauncher;

@Autowired
public static Batchconfig config;

@Autowired
private JobService jobService;

private final ScheduledExecutorService scheduler =
         Executors.newScheduledThreadPool(1);

public static Map<ScheduledFuture<Jobs>, Jobs> listLinked = new HashMap<>();
public static Map<Jobs, ScheduledFuture<Jobs>> listLinkedInverse = new HashMap<>();
List<Jobs> list;

@PostConstruct
public void init() {
    list = jobService.findAll();
    for (Jobs j : list) {
        if(j.isState()) {
            MyTask th = new MyTask(j);
            context.getAutowireCapableBeanFactory().autowireBean(th);
            ScheduledFuture<Jobs> jobHandler = (ScheduledFuture<Jobs>) scheduler.scheduleAtFixedRate(th, 0, 2, TimeUnit.SECONDS);
            listLinkedInverse.put(j, jobHandler);
            listLinked.put(jobHandler, j);
        }

    }
}

public void launchJob(Jobs myJob){
    MyTask th = new MyTask(myJob);
    context.getAutowireCapableBeanFactory().autowireBean(th);
    ScheduledFuture<Jobs> jobHandler = (ScheduledFuture<Jobs>) scheduler.scheduleAtFixedRate(th, 0, 2, TimeUnit.SECONDS);
    listLinkedInverse.put(myJob, jobHandler);
    listLinked.put(jobHandler, myJob);

}

public void cancelJob(Jobs j) {
    listLinkedInverse.get(j).cancel(true);
    listLinked.remove(listLinkedInverse.get(j));
    listLinkedInverse.remove(j);


}
}



@Component
public class MyTask extends Thread {

    @Autowired
    private JobLauncher jobLauncher;

    private Jobs job;

    @Autowired
    private Batchconfig config;

    public MyTask() {
    }

    public MyTask(Jobs job) {
        this.job = job;
    }
    public void run() {
            JobParameters jobParameters = new JobParametersBuilder().addLong("time", System.currentTimeMillis())
                    .addString("param", job.getParam()).toJobParameters();
            try {
                JobExecution jobExecution = jobLauncher.run(config.execute(job.getName()), jobParameters);
                System.out.println("Job's Status:::" + jobExecution.getStatus());
            } catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException
                    | JobParametersInvalidException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
    }

}
@组件
公共类调度程序{
@自动连线
私有应用程序上下文上下文;
@自动连线
公共静态JobLauncher JobLauncher;
@自动连线
公共静态批处理配置;
@自动连线
私人就业服务;
专用最终计划执行器服务计划程序=
Executors.newScheduledThreadPool(1);
public static Map listLinked=new HashMap();
公共静态映射listLinkedInverse=新HashMap();
名单;
@施工后
公共void init(){
list=jobService.findAll();
工作(j:列表){
if(j.isState()){
MyTask th=新的MyTask(j);
getAutowireCapableBeanFactory().autowireBean(th);
ScheduledFuture jobHandler=(ScheduledFuture)scheduler.scheduleAtFixedRate(th,0,2,TimeUnit.SECONDS);
listLinkedInverse.put(j,jobHandler);
listLinked.put(jobHandler,j);
}
}
}
public void launchJob(Jobs myJob){
MyTask th=新的MyTask(myJob);
getAutowireCapableBeanFactory().autowireBean(th);
ScheduledFuture jobHandler=(ScheduledFuture)scheduler.scheduleAtFixedRate(th,0,2,TimeUnit.SECONDS);
listLinkedInverse.put(myJob,jobHandler);
put(jobHandler,myJob);
}
公共职务(职务j){
listLinkedInverse.get(j).cancel(true);
移除(listLinkedInverse.get(j));
删除(j);
}
}
@组成部分
公共类MyTask扩展了线程{
@自动连线
私有JobLauncher JobLauncher;
私人工作;
@自动连线
私有批处理配置;
公共MyTask(){
}
公共MyTask(作业){
这个工作=工作;
}
公开募捐{
JobParameters JobParameters=新的JobParametersBuilder().addLong(“时间”,System.currentTimeMillis())
.addString(“param”,job.getParam()).toJobParameters();
试一试{
JobExecution JobExecution=jobLauncher.run(config.execute(job.getName()),jobParameters);
System.out.println(“作业状态::”+jobExecution.getStatus());
}捕获(JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException
|作业参数有效性异常(e){
e、 printStackTrace();
}捕获(例外e){
e、 printStackTrace();
}
}
}

是否定义了JobLauncher bean?是的,我尝试了,但仍然返回null。我尝试了此解决方案,但在配置TransactionManager时遇到问题。