gpt4 book ai didi

java - 我想创建一个 spring batch 项目,其中 batch 不使用我的数据源

转载 作者:行者123 更新时间:2023-11-30 08:31:38 24 4
gpt4 key购买 nike

我见过很多 Spring Batch 项目的例子,其中要么 (a) 定义了数据源,要么 (b) 没有定义数据源。

但是,在我的项目中,我希望我的业务逻辑能够访问数据源,但我希望 Spring Batch 不使用数据源。这可能吗?

这家伙有类似的问题:Spring boot + spring batch without DataSource

最佳答案

通常,在没有数据库的情况下使用 spring-batch 不是一个好主意,因为根据您定义的作业类型,可能会出现并发问题。因此,至少强烈建议使用内存数据库,特别是如果您计划在生产中使用该作业。

如果您不配置自己的数据源,则将 SpringBatch 与 SpringBoot 结合使用将初始化内存中的数据源。

考虑到这一点,让我将您的问题重新定义如下:我的业务逻辑可以使用除 springbatch 用于更新其 BATCH 表之外的另一个数据源吗?是的,它可以。事实上,您可以在 SpringBatch 作业中使用任意数量的数据源。只需使用按名称 Autowiring 。

我是这样操作的:我总是使用配置类,它定义了我在工作中必须使用的所有数据源

Configuration
public class DatasourceConfiguration {

@Bean
@ConditionalOnMissingBean(name = "dataSource")
public DataSource dataSource() {
// create datasource, that is used by springbatch
// for instance, create an inmemory datasource using the
// EmbeddedDatabaseFactory
return ...;
}

@Bean
@ConditionalOnMissingBean(name = "bl1datasource")
public DataSource bl1datasource() {
return ...; // your first datasource that is used in your businesslogic
}

@Bean
@ConditionalOnMissingBean(name = "bl2datasource")
public DataSource bl2datasource() {
return ...; // your second datasource that is used in your businesslogic
}
}

注意三点:

SpringBatch 正在寻找名称为“dataSource”的数据源,如果您没有提供此确切(大写的“S”)名称作为名称,Spring Batch 将尝试按类型 Autowiring ,如果它找到多个实例DataSource,它会抛出异常。

将您的数据源配置放在它自己的类中。不要将它们与您的工作定义放在同一个类中。 Spring 需要能够在加载上下文时尽早实例化名称为“dataSource”的数据源-SpringBean。在它开始实例化您的 Job-和 Step-Beans 之前。如果您将数据源定义与作业/步骤定义放在同一个类中,Spring 将无法正确执行此操作。

使用@ConditionalOnMissingBean 不是强制性的,但我发现这是一个很好的做法。它使更改单元/集成测试的数据源变得容易。只需在单元/IT 测试的 ContextConfiguration 中提供额外的测试配置,例如,用 inMemoryDataSource 覆盖“bl1Datasource”:

Configuration
public class TestBL1DatasourceConfiguration {

// overwritting bl1datasource with an inMemoryDatasource.
@Bean
public DataSource bl1datasource() {
return new EmbeddedDatabaseFactory.getDatabase();
}
}

为了使用业务逻辑数据源,按名称使用注入(inject):

@Component
public class PrepareRe1Re2BezStepCreatorComponent {

@Autowired
private StepBuilderFactory stepBuilderFactory;

@Autowired
private DataSource bl1datasource;

@Autowired
private DataSource bl2datasource;

public Step createStep() throws Exception {
SimpleStepBuilder<..., ...> builder =
stepBuilderFactory.get("astep") //
.<..., ...> chunk(100) //
.reader(createReader(bl1datasource)) //
.writer(createWriter(bl2datasource)); //

return builder.build();
}
}

此外,如果您想使用多个数据源,您可能需要考虑使用 XA-Datasources。

已编辑:

因为您似乎真的不想使用数据源,所以您必须实现自己的 BatchConfigurer ( http://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/core/configuration/annotation/BatchConfigurer.html )(正如 Michael Minella - SpringBatch 项目负责人 - 在上面指出的那样)。

您可以使用 org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer 的代码作为您自己实现的起点。只需删除所有数据源/事务管理器代码并保留初始化方法中 if (datasource === null) 部分的内容。这将初始化 MapBasedJobRepository 和 MapBasedJobExplorer。但同样,这不是生产环境中可用的解决方案,因为它不是线程安全的。

已编辑:

实现方式:

定义“businessDataSource”的配置类:

@Configuration
public class DataSourceConfigurationSimple {
DataSource embeddedDataSource;

@Bean
public DataSource myBusinessDataSource() {
if (embeddedDataSource == null) {
EmbeddedDatabaseFactory factory = new EmbeddedDatabaseFactory();
embeddedDataSource = factory.getDatabase();
}
return embeddedDataSource;
}
}

具体BatchConfigurer的实现:(当然,方法要实现...)

public class MyBatchConfigurer implements BatchConfigurer {
@Override
public JobRepository getJobRepository() throws Exception {
return null;
}

@Override
public PlatformTransactionManager getTransactionManager() throws Exception {
return null;
}

@Override
public JobLauncher getJobLauncher() throws Exception {
return null;
}

@Override
public JobExplorer getJobExplorer() throws Exception {
return null;
}
}

最后是主要配置和启动类:

@SpringBootApplication
@Configuration
@EnableBatchProcessing

// Importing MyBatchConfigurer will install your BatchConfigurer instead of
// SpringBatch default configurer.
@Import({DataSourceConfigurationSimple.class, MyBatchConfigurer.class})

public class SimpleTestJob {

@Autowired
private JobBuilderFactory jobs;

@Autowired
private StepBuilderFactory steps;

@Bean
public Job job() throws Exception {
SimpleJobBuilder standardJob = this.jobs.get(JOB_NAME)
.start(step1());
return standardJob.build();
}

protected Step step1() throws Exception {
TaskletStepBuilder standardStep1 = this.steps.get("SimpleTest_step1_Step")
.tasklet(tasklet());
return standardStep1.build();
}

protected Tasklet tasklet() {
return (contribution, context) -> {
System.out.println("tasklet called");
return RepeatStatus.FINISHED;
};
}

public static void main(String[] args) throws Exception {
SpringApplication.run(SimpleTestJob.class, args);
}
}

关于java - 我想创建一个 spring batch 项目,其中 batch 不使用我的数据源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40553985/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com