当前位置: 首页 > 知识库问答 >
问题:

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

周浩博
2023-03-14

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

这个家伙也有类似的问题:Spring boot+Spring batch没有DataSource

共有1个答案

屠嘉勋
2023-03-14

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

如果您没有配置自己的数据源,将SpringBatch与SpringBoot一起使用将初始化inmemory数据源。

考虑到这一点,让我重新定义您的问题如下:我的businesslogic是否可以使用springbatch所使用的其他数据源来更新它的批处理表?是的,它可以。事实上,您可以在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
    }
}

将数据源配置放在它自己的类中。不要将它们与jobdefinitions放在同一个类中。Spring需要能够在加载上下文的早期使用“DataSource”实例化datasource-SpringBean。在它开始实例化作业和步骤bean之前。如果将数据源定义与作业/步骤定义放在同一个类中,Spring将无法正确地执行此操作。

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

Configuration
public class TestBL1DatasourceConfiguration {

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

为了使用businesslogic数据源,请按名称使用注入:

@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();
    }
}

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

编辑:

如何实施:

@Configuration
public class DataSourceConfigurationSimple {
    DataSource embeddedDataSource;

    @Bean
    public DataSource myBusinessDataSource() {
        if (embeddedDataSource == null) {
            EmbeddedDatabaseFactory factory = new EmbeddedDatabaseFactory();
            embeddedDataSource = factory.getDatabase();
        }
        return embeddedDataSource;
    }
}
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);
    }
}
 类似资料:
  • 我试图用mvn组织构建一个aem项目。阿帕奇。专家插件:maven原型插件:2.4:generate-DarchetypeGroupId=com。土砖花岗岩原型-DarchetypeArtifactId=aem项目原型-DarchetypeVersion=12-DarchetypeCatalog=https://repo.adobe.com/nexus/content/groups/public/

  • 我有这个功能: 这是为了防止用户在引用值上创建重复的Compra。 我在这里使用它: 当前用户正在创建“Compra”,但如果Compra被取消,您应该能够使用“Referenceia”值,因为Compra已被删除。然而,即使是thouh Compra被取消,用于该Compra的“参考”也不能再使用了。 我想添加一个条件来验证,当Compra'estatus'值为'aprobado'时,用户无法继

  • 我在这个问题上也有同样的问题 如何使用android中的回收器视图将事件放在日历中 //Event.java 我尝试了很多,但它甚至不工作。我的事件。我要在另一个适配器中使用java。也许在onBindViewHolder中。

  • 首先,打开Android Studio并选择Create new Project,然后它会让你输入一个名字,你可以任意取一个名字,比如:Weather App。然后你需要输入公司域名。如果你不会真正发布这个app,这个字段就不是特别重要了,但是如果你有的话可以使用自己的域名。然后任意选择一个目录作为这个项目的保存地址。 下一步,它会让你选择最小的API版本。我们选择API 15,因为我们有一个库需

  • 我正在尝试使用gradle编译一个war文件以部署到JBoss 7.1 AS,但编译失败(找不到ServletContext)…… gradle.build.见下文 错误: /workspace/agile runner/src/main/Java/com/agile runner/web/config/agilerunnerapplicationinitializer . Java:20:找不到

  • 从一个char数组,我想构造一个流来使用Java8特性,如过滤器和映射。 第一种方法不起作用(原因:将cStream更改为)。注释行也不起作用(原因:类型数组中的方法不适用于参数())。 我知道,如果将更改为,那么使用就可以正常工作。但我不想每次都将每个转换为或在需要对数组使用流库时将其转换为列表。