我正在使用 Spring-boot 3.1.4 和 Spring Batch Framework 5.0.3。
第一个问题:当我使用 Spring-boot 启动我的项目时,我的所有 bean 都已实例化,我可以使用 @Autowiring 来注入它们。 当我启动端到端测试时,我的所有 bean 都没有实例化,并且出现此错误。
No qualifying bean of type 'com.example.demo.job.MiniTask' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
我忘记了测试依赖吗?
测试课
@SpringBatchTest
@SpringJUnitConfig(classes = { JobConfigurationTest.class })
class DemoApplicationTests {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Test
void contextLoads() {
}
@Test
public void testJob(Job job) throws Exception {
this.jobLauncherTestUtils.setJob(job);
JobExecution jobExecution = jobLauncherTestUtils.launchJob();
Assertions.assertEquals("COMPLETED", jobExecution.getExitStatus().getExitCode());
}
}
配置类:
@Configuration
public class JobConfiguration extends DefaultBatchConfiguration {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
.addScript("/org/springframework/batch/core/schema-h2.sql")
.build();
}
@Bean
public JdbcTransactionManager transactionManager(DataSource dataSource) {
return new JdbcTransactionManager(dataSource);
}
@Bean
public Step step(JobRepository jobRepository, JdbcTransactionManager transactionManager,MiniTask miniTask){
return new StepBuilder("step", jobRepository).tasklet(miniTask,transactionManager).allowStartIfComplete(true).build();
}
}
SpringBootApplication.class
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args){
SpringApplication.exit(SpringApplication.run(DemoApplication.class, args));
}
}
任务
@Component("miniTask")
public class MiniTask implements Tasklet {
private static Logger LOG = LoggerFactory.getLogger(MiniTask.class);
public MiniTask() {
LOG.info("Tasklet constructor");
}
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
LOG.info("Launch task");
return RepeatStatus.FINISHED;
}
}
第二个问题:当我启动项目时,我的项目不会自动启动,并且我的项目中只有一项工作。
您没有共享测试类导入的
JobConfigurationTest
的内容,但其中似乎没有定义Job
类型的bean,因此出现错误。因此,要解决这个问题,您需要在该类中定义一个类型为 Job
的 bean。
对于 Spring Boot,我建议使用
@SpringBatchTest
,它将加载主应用程序上下文(即定义您的作业的生产环境),因此不需要创建测试上下文,除非您想覆盖主应用程序上下文一个。
以下作品(使用 Spring Boot 3.1.5 进行测试,使用此配置从 start.spring.io 生成项目)。
作业配置类:
package com.example.demo;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
public class JobConfiguration {
@Bean
public Job job(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new JobBuilder("job", jobRepository)
.start(new StepBuilder("step", jobRepository)
.tasklet((contribution, chunkContext) -> {
System.out.println("hello world");
return RepeatStatus.FINISHED;
}, transactionManager)
.build())
.build();
}
}
主要应用类:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
测试班:
package com.example.demo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.batch.test.context.SpringBatchTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
@SpringBatchTest
class DemoApplicationTests {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Test
void contextLoads() {
}
@Test
void testJob(@Autowired Job job) throws Exception {
this.jobLauncherTestUtils.setJob(job);
JobExecution jobExecution = jobLauncherTestUtils.launchJob();
Assertions.assertEquals("COMPLETED", jobExecution.getExitStatus().getExitCode());
}
}