web-dev-qa-db-ja.com

スプリングブート+ DataSourceなしのスプリングバッチ

Spring Bootプロジェクト内でSpringバッチを構成しようとしていますが、データソースなしで使用したいと思います。 ResourcelessTransactionManagerを使用する方法を見つけましたが、機能させることができません。問題は、すでに3つの別のdataSourcesが定義されていることですが、それらのいずれもspringBatchで使用したくありません。

私はデフォルトの実装DefaultBatchConfigurerを確認しましたが、dataSourceが見つからない場合は、私が望んでいるとおりに動作します。問題は、私が3つ持っていて、どれも使いたくないということです。

私はそれを望まないので、hsqlやその他をメモリDBで使用することを勧めないでください。

12
Majky

この問題を回避するには、DefaultBatchConfigurerクラスを拡張して、DataSourceを無視するようにします。その結果、マップベースのJobRepositoryが構成されます。

例:

@Configuration
@EnableBatchProcessing
public class BatchConfig extends DefaultBatchConfigurer {   

    @Override
    public void setDataSource(DataSource dataSource) {
        //This BatchConfigurer ignores any DataSource
    }
}
13
Nandish

私の場合、Cassandraにデータを永続化します。 spring-boot-starter-batchを使用している場合、まだ実装されていないDataSourceが提供されることが予想されますが、次の手順のように構成をだますことができます。

ステップ1:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class SampleSpringBatchApplication{

    public static void main(String[] args) {
        System.setProperty("spring.devtools.restart.enabled", "true");
        SpringApplication.run(SampleSpringBatchApplication.class, args);
    }

}

ステップ2:

    @Configuration
    @EnableBatchProcessing
    public class SampleBatchJob extends DefaultBatchConfigurer {

        //..

        @Override
        public void setDataSource(DataSource dataSource) {
        }

        //..
    }
5
Rzv Razvan

構成に複数のDataSourceがある場合(それらを使用するかどうかに関係なく)、独自のBatchConfigurerを定義する必要があります。フレームワークがそのような状況で何をすべきかを知る唯一の方法です。

BatchConfigurerの詳細については、こちらのドキュメントをご覧ください。 http://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/core/configuration/annotation /BatchConfigurer.html

3
Michael Minella

同様の問題があり、Spring Boot JDBCを使用していて、DBにSpringバッチテーブルを格納したくありませんでしたが、それでもDataSourceにSpringのトランザクション管理を使用したいと考えました。

最終的に、独自のBatchConfigurerを実装しました。

@Component
public class TablelessBatchConfigurer implements BatchConfigurer {
    private final PlatformTransactionManager transactionManager;
    private final JobRepository jobRepository;
    private final JobLauncher jobLauncher;
    private final JobExplorer jobExplorer;
    private final DataSource dataSource;

    @Autowired
    public TablelessBatchConfigurer(DataSource dataSource) {
        this.dataSource = dataSource;
        this.transactionManager = new DataSourceTransactionManager(this.dataSource);

        try {
            final MapJobRepositoryFactoryBean jobRepositoryFactory = new MapJobRepositoryFactoryBean(this.transactionManager);
            jobRepositoryFactory.afterPropertiesSet();
            this.jobRepository = jobRepositoryFactory.getObject();

            final MapJobExplorerFactoryBean jobExplorerFactory = new MapJobExplorerFactoryBean(jobRepositoryFactory);
            jobExplorerFactory.afterPropertiesSet();
            this.jobExplorer = jobExplorerFactory.getObject();

            final SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
            simpleJobLauncher.setJobRepository(this.jobRepository);
            simpleJobLauncher.afterPropertiesSet();
            this.jobLauncher = simpleJobLauncher;
        } catch (Exception e) {
            throw new BatchConfigurationException(e);
        }
    }
    // ... override getters
}

イニシャライザをfalseに設定する

spring.batch.initializer.enabled=false
1
Richard Vašek

@SpringBootApplicationでDataSourceAutoConfigurationを除外してみてください。以下のサンプルコードを参照してください。

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@EnableBatchProcessing
public class SampleBatchApplication {

@Autowired
private JobBuilderFactory jobs;

@Autowired
private StepBuilderFactory steps;

@Bean
protected Tasklet tasklet() {

    return new Tasklet() {
        @Override
        public RepeatStatus execute(StepContribution contribution, ChunkContext context) {
            return RepeatStatus.FINISHED;
        }
    };
}

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

@Bean
protected Step step1() throws Exception {
    return this.steps.get("step1").tasklet(tasklet()).build();
}

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

そしてサンプルテストクラス

import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.rule.OutputCapture;
import static org.assertj.core.api.Assertions.assertThat;
public class SampleBatchApplicationTests {
@Rule
public OutputCapture outputCapture = new OutputCapture();

@Test
public void testDefaultSettings() throws Exception {
    assertThat(SpringApplication.exit(SpringApplication.run(SampleBatchApplication.class))).isEqualTo(0);
    String output = this.outputCapture.toString();
    assertThat(output).contains("completed with the following parameters");
  }
}
1
abaghel