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

标签 java spring spring-batch

我见过很多 Spring Batch 项目的示例,其中 (a) 定义了数据源,或 (b) 未定义数据源。

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

这个人也有类似的问题:Spring boot + spring batch without DataSource

最佳答案

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

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

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

我是这样做的: 我总是使用 Configuration 类,它定义了我必须在作业中使用的所有数据源

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-Bean 和 Step-Bean 之前。如果您将数据源定义与作业/步骤定义放在同一个类中,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 )(正如 SpringBatch 项目负责人 Michael Minella 上面指出的那样)。

您可以使用 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/

相关文章:

java - 编译器错误说我不重写抽象方法 keyReleased

java - Rest Assured 中的 Xml 断言

java - Android 特定用户界面

java - @PathVariable 的自定义参数解析器

java - Spring 批处理 DB 到 JSON 文件

Java Spring Batch - 资源文件未注入(inject)到tasklet中

java - 我们是否必须在 java.io.File 路径中使用系统相关的文件分隔符?

java - Spring JPA hibernate H2

java - @Resource 注释无法与 JBoss5.0.1 一起正常工作

java - Marshaller 必须支持 Spring Batch 拆分作业中编码对象错误的类