Spring boot + spring batch without DataSource

前端 未结 5 725
余生分开走
余生分开走 2020-12-19 00:51

I\'m trying to configure spring batch inside spring boot project and I want to use it without data source. I\'ve found that ResourcelessTransactionManager is th

相关标签:
5条回答
  • 2020-12-19 00:51

    I got around this problem by extending the DefaultBatchConfigurer class so that it ignores any DataSource, as a consequence it will configure a map-based JobRepository.

    Example:

    @Configuration
    @EnableBatchProcessing
    public class BatchConfig extends DefaultBatchConfigurer {   
    
        @Override
        public void setDataSource(DataSource dataSource) {
            //This BatchConfigurer ignores any DataSource
        }
    }
    
    0 讨论(0)
  • 2020-12-19 00:58

    We had the similar problem, we were using spring boot JDBC and we did not want to store spring batch tables in the DB, but we still wanted to use spring's transaction management for our DataSource.

    We ended up implementing own 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
    }
    

    and setting up initializer to false

    spring.batch.initializer.enabled=false
    
    0 讨论(0)
  • 2020-12-19 01:02

    If you have more than one DataSource in your configuration (regardless of if you want to use them or not) you need to define your own BatchConfigurer. It's the only way the framework knows what to do in situations like that.

    You can read more about the BatchConfigurer in the documentation here: http://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/core/configuration/annotation/BatchConfigurer.html

    0 讨论(0)
  • 2020-12-19 01:07

    In my case I persist data to Cassandra. If you are using spring-boot-starter-batch it is expected to provide a DataSource which is not yet implemented but you can trick the configuration like in the following steps:

    Step1:

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

    Step2:

        @Configuration
        @EnableBatchProcessing
        public class SampleBatchJob extends DefaultBatchConfigurer {
    
            //..
    
            @Override
            public void setDataSource(DataSource dataSource) {
            }
    
            //..
        }
    
    0 讨论(0)
  • 2020-12-19 01:12

    You can try excluding the DataSourceAutoConfiguration in @SpringBootApplication. See the sample code below.

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

    And sample test class

    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");
      }
    }
    
    0 讨论(0)
提交回复
热议问题