Introduktion til Spring Batch

1. Introduktion

I denne artikel vil vi fokusere på en praktisk, kodefokuseret introduktion til Spring Batch. Spring Batch er en behandlingsramme designet til robust udførelse af job.

Den nuværende version 3.0, som understøtter Spring 4 og Java 8. Den rummer også JSR-352, som er en ny java-specifikation til batchbehandling.

Her er et par interessante og praktiske brugstilfælde af rammen.

2. Grundlæggende om workflow

Forårsbatch følger den traditionelle batcharkitektur, hvor et jobopbevaringsarbejde planlægger og interagerer med jobbet.

Et job kan have mere end et trin - og hvert trin følger typisk rækkefølgen af ​​læsning af data, behandling og skrivning af dem.

Og selvfølgelig vil rammen gøre det meste af det tunge løft for os her - især når det kommer til det lave niveau vedholdenhedsarbejde med at håndtere job - ved hjælp af sqlite til jobopbevaringsstedet.

2.1. Vores eksempler på anvendelse

Den enkle usecase, vi skal tackle her, er - vi migrerer nogle finansielle transaktionsdata fra CSV til XML.

Inputfilen har en meget enkel struktur - den indeholder en transaktion pr. Linje, der består af: et brugernavn, bruger-id, datoen for transaktionen og beløbet:

brugernavn, bruger-id, transaktionsdato, transaktionsbeløb devendra, 1234, 31/10/2015, 10000 john, 2134, 3/12/2015, 12321 robin, 2134, 2/02/2015, 23411

3. Maven POM

Afhængigheder, der kræves til dette projekt, er fjederkerne, fjederbatch og sqlite jdbc-stik:

   org.xerial sqlite-jdbc 3.15.1 org.springframework spring-oxm 5.2.0.RELEASE org.springframework spring-jdbc 5.2.0.RELEASE org.springframework.batch spring-batch-core 4.2.0.RELEASE 

4. Spring Batch Config

Den første ting, vi skal gøre, er at konfigurere Spring Batch med XML:

Naturligvis er en Java-konfiguration også tilgængelig:

@Configuration @EnableBatchProcessing public class SpringConfig {@Value ("org / springframework / batch / core / schema-drop-sqlite.sql") private Ressource dropReopsitoryTables; @Value ("org / springframework / batch / core / schema-sqlite.sql") private Ressource dataReopsitorySchema; @Bean offentlig DataSource dataSource () {DriverManagerDataSource dataSource = ny DriverManagerDataSource (); dataSource.setDriverClassName ("org.sqlite.JDBC"); dataSource.setUrl ("jdbc: sqlite: repository.sqlite"); returnere datakilde; } @Bean public DataSourceInitializer dataSourceInitializer (DataSource dataSource) kaster MalformedURLException {ResourceDatabasePopulator databasePopulator = ny ResourceDatabasePopulator (); databasePopulator.addScript (dropReopsitoryTables); databasePopulator.addScript (dataReopsitorySchema); databasePopulator.setIgnoreFailedDrops (sand); DataSourceInitializer initializer = ny DataSourceInitializer (); initializer.setDataSource (dataSource); initializer.setDatabasePopulator (databasePopulator); initialiseringsretur; } privat JobRepository getJobRepository () kaster undtagelse {JobRepositoryFactoryBean fabrik = ny JobRepositoryFactoryBean (); factory.setDataSource (dataSource ()); factory.setTransactionManager (getTransactionManager ()); factory.afterPropertiesSet (); returner (JobRepository) fabrik.getObject (); } privat PlatformTransactionManager getTransactionManager () {returner ny ResourcelessTransactionManager (); } offentlig JobLauncher getJobLauncher () kaster undtagelse {SimpleJobLauncher jobLauncher = ny SimpleJobLauncher (); jobLauncher.setJobRepository (getJobRepository ()); jobLauncher.afterPropertiesSet (); return jobLauncher; }}

5. Spring Batch Job Config

Lad os nu skrive vores jobbeskrivelse for CSV til XML-arbejde:

                           com.baeldung.spring_batch_intro.model.Transaction 

Og selvfølgelig den lignende Java-baserede jobkonfiguration:

offentlig klasse SpringBatchConfig {@Autowired private JobBuilderFactory job; @Autowired private StepBuilderFactory trin; @Value ("input / record.csv") privat Ressource inputCsv; @Value ("fil: xml / output.xml") privat ressource outputXml; @Bean public ItemReader itemReader () kaster UnexpectedInputException, ParseException {FlatFileItemReader reader = ny FlatFileItemReader (); DelimitedLineTokenizer tokenizer = ny DelimitedLineTokenizer (); String [] tokens = {"brugernavn", "bruger-id", "transaktionsdato", "beløb"}; tokenizer.setNames (tokens); reader.setResource (inputCsv); DefaultLineMapper lineMapper = ny DefaultLineMapper (); lineMapper.setLineTokenizer (tokenizer); lineMapper.setFieldSetMapper (ny RecordFieldSetMapper ()); reader.setLineMapper (lineMapper); returlæser; } @Bean public ItemProcessor itemProcessor () {returner ny CustomItemProcessor (); } @Bean public ItemWriter itemWriter (Marshaller marshaller) kaster MalformedURLException {StaxEventItemWriter itemWriter = ny StaxEventItemWriter (); itemWriter.setMarshaller (marshaller); itemWriter.setRootTagName ("transactionRecord"); itemWriter.setResource (outputXml); returnereWriter; } @Bean offentlig Marshaller marshaller () {Jaxb2Marshaller marshaller = ny Jaxb2Marshaller (); marshaller.setClassesToBeBound (ny klasse [] {Transaction.class}); returnere marshaller; } @Bean-beskyttet trin trin 1 (ItemReader-læser, ItemProcessor-processor, ItemWriter-forfatter) {return steps.get ("step1"). klump (10) .læser (læser) .processor (processor). forfatter (forfatter) .build (); } @Bean (name = "firstBatchJob") offentligt jobjob (@Qualifier ("trin1") Trin trin1) {returner jobs.get ("firstBatchJob"). Start (trin1) .build (); }}

OK, så nu hvor vi har hele konfigurationen, lad os nedbryde den og begynde at diskutere det.

5.1. Læs data og opret objekter med ItemReader

Først konfigurerede vi cvsFileItemReader som vil læse dataene fra record.csv og konvertere det til Transaktion objekt:

@SuppressWarnings ("restriktion") @XmlRootElement (name = "transactionRecord") offentlig klasse Transaktion {privat streng brugernavn; privat int userId; privat LocalDateTime-transaktionsdato; privat dobbeltbeløb / * getters og settere for attributterne * / @Override public String toString () {return "Transaction [username =" + username + ", userId =" + userId + ", transactionDate =" + transactionDate + ", amount =" + beløb + "]"; }}

For at gøre det - det bruger en brugerdefineret kortlægger:

offentlig klasse RecordFieldSetMapper implementerer FieldSetMapper {public Transaction mapFieldSet (FieldSet fieldSet) kaster BindException {DateTimeFormatter formatter = DateTimeFormatter.ofPattern ("d / M / ååå"); Transaktionstransaktion = ny Transaktion (); transaction.setUsername (fieldSet.readString ("brugernavn")); transaction.setUserId (fieldSet.readInt (1)); transaction.setAmount (fieldSet.readDouble (3)); String dateString = fieldSet.readString (2); transaction.setTransactionDate (LocalDate.parse (dateString, formatter) .atStartOfDay ()); returtransaktion }}

5.2. Behandling af data med ItemProcessor

Vi har oprettet vores egen vareprocessor, CustomItemProcessor. Dette behandler ikke noget relateret til transaktionsobjektet - alt det gør er at overføre det originale objekt, der kommer fra læseren til forfatteren:

offentlig klasse CustomItemProcessor implementerer ItemProcessor {public Transaction process (Transaction item) {return item; }}

5.3. Skrivning af objekter til FS med ItemWriter

Endelig skal vi gemme dette transaktion i en xml-fil placeret på xml / output.xml:

5.4. Konfiguration af batchjob

Så alt hvad vi skal gøre er at forbinde prikkerne med et job - ved hjælp af batch: job syntaks.

Bemærk begå-interval - det er antallet af transaktioner, der skal gemmes i hukommelsen, inden batchen tildeles itemWriter; det holder transaktionerne i hukommelsen indtil dette punkt (eller indtil slutningen af ​​inputdataene er stødt):

5.5. Kørsel af batchjob

Det er det - lad os nu konfigurere og køre alt:

public class App {public static void main (String [] args) {// Spring Java config AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext (); context.register (SpringConfig.class); context.register (SpringBatchConfig.class); context.refresh (); JobLauncher jobLauncher = (JobLauncher) context.getBean ("jobLauncher"); Jobjob = (Job) context.getBean ("firstBatchJob"); System.out.println ("Starter batchjob"); prøv {JobExecution-udførelse = jobLauncher.run (job, nye JobParameters ()); System.out.println ("Jobstatus:" + udførelse.getStatus ()); System.out.println ("Job afsluttet"); } fange (Undtagelse e) {e.printStackTrace (); System.out.println ("Job mislykkedes"); }}}

6. Konklusion

Denne vejledning giver dig en grundlæggende idé om hvordan man arbejder med Spring Batch og hvordan man bruger det i en simpel usecase.

Det viser, hvordan du nemt kan udvikle din batchbehandlingspipeline, og hvordan du kan tilpasse forskellige faser i læsning, behandling og skrivning.

Det fuld implementering af denne vejledning kan findes i github-projektet - dette er et Eclipse-baseret projekt, så det skal være let at importere og køre som det er.


$config[zx-auto] not found$config[zx-overlay] not found