如何创建无Spring Batch元数据的Spring Boot Batch项目(适配v2.7.0)
Spring Boot 2.7.x 无持久化元数据Spring Batch实现方案
MapJobRepositoryFactoryBean在Spring Batch 4.3+(对应Spring Boot 2.4+)被标记废弃的核心原因是其基于内存Map的实现存在线程安全缺陷,官方不推荐在生产环境使用。目前2.7版本有两种可行的替代方案,效果和原内存Map模式一致,元数据不会持久化到外部存储,应用停止后自动清除。
方案一:官方推荐方案(无废弃API,生产可用,兼容后续版本升级)
官方推荐使用嵌入式内存数据库搭配JDBC组件实现内存态元数据存储,稳定性、线程安全性远高于原Map实现,是2.4+版本的标准实现方式。
- 引入嵌入式内存数据库H2依赖,无需额外部署数据库服务:
Maven 依赖(pom.xml):
Gradle 依赖:<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency>runtimeOnly 'com.h2database:h2' - 添加配置(application.properties),默认配置即可满足需求,显式配置更清晰:
# 嵌入式数据库场景自动初始化Batch元数据表,应用停止后数据自动清除 spring.batch.jdbc.initialize-schema=embedded # 可根据自身需求决定是否关闭项目启动时自动执行Batch任务 spring.batch.job.enabled=false - 自定义配置(可选,默认自动配置即可直接使用):如果需要自定义JobLauncher线程池等参数,可添加如下配置类,不需要完全重写所有组件:
import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.launch.support.SimpleJobLauncher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.task.TaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import javax.sql.DataSource; @Configuration public class BatchConfig extends DefaultBatchConfigurer { public BatchConfig(DataSource dataSource) { super(dataSource); } @Override public JobLauncher getJobLauncher() { SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); jobLauncher.setJobRepository(getJobRepository()); jobLauncher.setTaskExecutor(batchTaskExecutor()); try { jobLauncher.afterPropertiesSet(); } catch (Exception e) { throw new RuntimeException("JobLauncher初始化失败", e); } return jobLauncher; } @Bean public TaskExecutor batchTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(4); executor.setMaxPoolSize(8); executor.setQueueCapacity(20); executor.setThreadNamePrefix("batch-task-"); executor.initialize(); return executor; } }
方案二:原Map逻辑兼容方案(无额外依赖,2.7版本可用,不推荐生产使用)
如果不想引入额外依赖,希望完全沿用原内存Map的逻辑,2.7版本中相关类并未被移除,仅标记为废弃。你之前的代码失效是因为实例化工厂Bean后没有调用afterPropertiesSet()完成初始化,同时缺少事务管理器配置,修正后代码如下:
import org.springframework.batch.core.configuration.BatchConfigurationException; import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer; import org.springframework.batch.core.explore.JobExplorer; import org.springframework.batch.core.explore.support.MapJobExplorerFactoryBean; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.launch.support.SimpleJobLauncher; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean; import org.springframework.batch.support.transaction.ResourcelessTransactionManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.PlatformTransactionManager; @Configuration public class MetaDataConfiguration { @Bean public PlatformTransactionManager resourcelessTransactionManager() { return new ResourcelessTransactionManager(); } @Bean public DefaultBatchConfigurer batchConfigurer() { return new DefaultBatchConfigurer() { private final JobRepository jobRepository; private final JobExplorer jobExplorer; private final JobLauncher jobLauncher; { try { MapJobRepositoryFactoryBean jobRepositoryFactory = new MapJobRepositoryFactoryBean(); jobRepositoryFactory.setTransactionManager(resourcelessTransactionManager()); // 必须手动调用初始化方法 jobRepositoryFactory.afterPropertiesSet(); this.jobRepository = jobRepositoryFactory.getObject(); MapJobExplorerFactoryBean jobExplorerFactory = new MapJobExplorerFactoryBean(jobRepositoryFactory); // 必须手动调用初始化方法 jobExplorerFactory.afterPropertiesSet(); this.jobExplorer = jobExplorerFactory.getObject(); SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher(); simpleJobLauncher.setJobRepository(jobRepository); simpleJobLauncher.afterPropertiesSet(); this.jobLauncher = simpleJobLauncher; } catch (Exception e) { throw new BatchConfigurationException(e); } } @Override public JobRepository getJobRepository() { return jobRepository; } @Override public JobExplorer getJobExplorer() { return jobExplorer; } @Override public JobLauncher getJobLauncher() { return jobLauncher; } }; } }
注意:方案二使用的Map相关工厂类在Spring Boot 3.x(Spring Batch 5.x)版本中已被彻底移除,如果后续有版本升级计划,优先选择方案一避免二次改造。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

