web-dev-qa-db-fra.com

Spring boot + spring batch without DataSource

J'essaie de configurer le lot de printemps dans le projet de démarrage de printemps et je veux l'utiliser sans source de données. J'ai trouvé que ResourcelessTransactionManager est le chemin à parcourir mais je ne peux pas le faire fonctionner. Le problème est que j'ai déjà défini 3 autres sources de données, mais je ne veux en utiliser aucune dans springBatch.

J'ai vérifié l'implémentation par défaut DefaultBatchConfigurer et s'il n'est pas en mesure de trouver dataSource, il fera exactement ce que je veux. Le problème est que j'en ai 3 et que je ne veux pas en utiliser.

Veuillez ne pas suggérer d'utiliser hsql ou autre dans la mémoire DB car je ne veux pas cela.

12
Majky

J'ai contourné ce problème en étendant la classe DefaultBatchConfigurer afin qu'elle ignore toute DataSource, par conséquent, elle configurera un JobRepository basé sur une carte.

Exemple:

@Configuration
@EnableBatchProcessing
public class BatchConfig extends DefaultBatchConfigurer {   

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

Dans mon cas, je persiste pour Cassandra. Si vous utilisez spring-boot-starter-batch il est prévu de fournir un DataSource qui n'est pas encore implémenté mais vous pouvez tromper la configuration comme dans les étapes suivantes:

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

}

Étape 2:

    @Configuration
    @EnableBatchProcessing
    public class SampleBatchJob extends DefaultBatchConfigurer {

        //..

        @Override
        public void setDataSource(DataSource dataSource) {
        }

        //..
    }
5
Rzv Razvan

Si vous avez plusieurs DataSource dans votre configuration (que vous les utilisiez ou non), vous devez définir votre propre BatchConfigurer. C'est la seule façon pour le framework de savoir quoi faire dans des situations comme ça.

Vous pouvez en savoir plus sur BatchConfigurer dans la documentation ici: http://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/core/configuration/annotation /BatchConfigurer.html

3
Michael Minella

Nous avons eu le même problème, nous utilisions Spring Boot JDBC et nous ne voulions pas stocker les tables de lots Spring dans la base de données, mais nous voulions toujours utiliser la gestion des transactions de Spring pour notre DataSource.

Nous avons fini par implémenter notre propre 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
}

et configuration de l'initialiseur sur false

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

Vous pouvez essayer d'exclure DataSourceAutoConfiguration dans @SpringBootApplication. Voir l'exemple de code ci-dessous.

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

Et exemple de classe de test

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