You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot从2.7.x迁移到3.1.6时Spring Batch日志警告求助

Spring Boot 3.1.6迁移后Spring Batch的INFO级提示处理方案

迁移后出现的INFO日志

[16-12-2023 08:18:04.248] [] [] INFO
[o.s.b.c.c.annotation.BatchRegistrar] Finished Spring Batch
infrastructure beans configuration in 7 ms.
[16-12-2023 08:18:08.626] [] [] INFO [o.s.b.c.r.s.JobRepositoryFactoryBean] No database type set, using
meta data indicating: MYSQL
[16-12-2023 08:18:08.698] [] [] INFO [o.s.b.c.c.a.BatchObservabilityBeanPostProcessor] No Micrometer
observation registry found, defaulting to ObservationRegistry.NOOP
[16-12-2023 08:18:08.708] [] [] INFO [o.s.b.c.c.a.BatchObservabilityBeanPostProcessor] No Micrometer
observation registry found, defaulting to ObservationRegistry.NOOP
[16-12-2023 08:18:08.712] [] [] INFO [o.s.b.c.l.support.SimpleJobLauncher] No TaskExecutor has been set,
defaulting to synchronous executor.

相关代码片段

数据源配置类

@Configuration
public class DataSourceBean {

    @Value("${db.datasource.driver-class-name}")
    private String driverName;

    @Value("${db.datasource.url}")
    private String url;

    @Value("${db.datasource.username}")
    private String userName;

    @Value("${db.datasource.password}")
    private String password;

    @Bean(name="dataSource")
    public DataSource dbDatasource() {
        return DataSourceBuilder.create()
            .driverClassName(driverName)
            .url(url)
            .username(userName)
            .password(password)
            .build();
    }

    @Primary
    @Bean(name = "primaryEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put("hibernate.hbm2ddl.auto", "update");
        return builder
                .dataSource(dbDatasource())
                .packages("com.gigi.apm.card")
                .persistenceUnit("default")
                .properties(properties)
                .build();
    }
}

Batch配置类

@Configuration
@EnableBatchProcessing
@EntityScan(basePackages = {"com.gigi.apm.card"})
@EnableJpaRepositories(entityManagerFactoryRef = "primaryEntityManagerFactory",transactionManagerRef = "batchTransactionManager",
    basePackages="com.gigi.apm.card.batch.repository")
public class ApmBatchConfig {

    @Value("${db.batch.batch-size}")
    private int batchSize;

    @Autowired
    @Qualifier("dataSource")
    public DataSource dataSource;

    @Autowired
    private ApmTransactionRepository repository;

    @Bean
    @StepScope
    public Tasklet deleteApmTransactionTasklet() {
        return new DeleteApmTransactionTasklet(repository,batchSize);
    }

    @Bean(name = "transactionManager")
    @Primary
    public JpaTransactionManager batchTransactionManager(@Qualifier("primaryEntityManagerFactory")
                                                             EntityManagerFactory
                                                                     primaryEntityManagerFactory) {
        return new JpaTransactionManager(primaryEntityManagerFactory);
    }

    @Bean
    public Job deleteCompletedTransaction(Step deleteStep,JobRepository jobRepository) {
        return new JobBuilder("deleteCompletedTransaction",jobRepository)
                .incrementer(new RunIdIncrementer())
                .start(deleteStep)
                .build();
    }

    @Bean("step1")
    public Step deleteTransaction(Tasklet deleteApmTransactionTasklet,
                                   PlatformTransactionManager transactionManager,JobRepository jobRepository) {
        return new StepBuilder("deleteTransaction", jobRepository)
                .allowStartIfComplete(Boolean.TRUE)
                .tasklet(deleteApmTransactionTasklet, transactionManager)
                .build();
    }
}

Tasklet实现类

public class DeleteApmTransactionTasklet implements Tasklet {

    private static final Logger LOGGER = LoggerFactory.getLogger(DeleteApmTransactionTasklet.class);
    private static final int THREAD_DELAY = 1000;
    private static final String TRANSACTION_STATUS="DONE";

    private int batchSize;

    private final ApmTransactionRepository repository;

    public DeleteApmTransactionTasklet(ApmTransactionRepository repository,int batchSize) {
        this.repository= repository;
        this.batchSize=batchSize;
    }

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        try {
            LOGGER.info("Delete action is started.");
            long count = repository.getCountByStatus(TRANSACTION_STATUS);
            LOGGER.info("Number of transactions to be deleted {}", count);
            while (count > 0) {
                 repository.deleteTrnInBatch(TRANSACTION_STATUS, batchSize);
                 Thread.sleep(1000);
                 count = count - batchSize;
            }
            LOGGER.info("Completed transactions are deleted successfully");
        } catch (DataAccessException exception) {
            LOGGER.error("Transactions are not deleted successfully because of error {}", exception);
            return RepeatStatus.CONTINUABLE;
        }
        return RepeatStatus.FINISHED;
    }
}

Repository与启动类

@Repository
public interface ApmTransactionRepository extends JpaRepository<ApmTransaction, String> {

}

@SpringBootApplication
public class ApmBatchApplication {
    public static void main(String[] args) {
        System.exit(SpringApplication.exit(SpringApplication.run(DecoupledBatchApplication.class, args)));
    }
}

日志提示的处理建议

这些INFO级日志本身不是错误,但可根据需求优化配置:

  1. No database type set, using meta data indicating: MYSQL
    Spring Batch已自动检测数据库类型,若需显式指定,可在配置JobRepository时添加数据库类型设置:

    @Bean
    public JobRepository jobRepository(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) throws Exception {
        JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
        factory.setDataSource(dataSource);
        factory.setTransactionManager(batchTransactionManager(entityManagerFactory));
        factory.setDatabaseType(DatabaseType.MYSQL.name());
        return factory.getObject();
    }
    
  2. No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP
    若要启用Spring Batch的可观测能力,添加Micrometer相关依赖(以Maven为例):

    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    

    添加后Spring会自动配置ObservationRegistry,该日志提示会消失。

  3. No TaskExecutor has been set, defaulting to synchronous executor
    当前JobLauncher使用同步执行器,若需异步执行Job,可配置异步TaskExecutor:

    @Bean
    public SimpleJobLauncher jobLauncher(JobRepository jobRepository) throws Exception {
        SimpleJobLauncher launcher = new SimpleJobLauncher();
        launcher.setJobRepository(jobRepository);
        launcher.setTaskExecutor(new SimpleAsyncTaskExecutor());
        return launcher;
    }
    

内容的提问来源于stack exchange,提问作者cyrille gate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 03:01:10