Introduksjon til Spring Batch

1. Introduksjon

I denne artikkelen skal vi fokusere på en praktisk, kodefokusert intro til Spring Batch. Spring Batch er et behandlingsrammeverk designet for robust utføring av jobber.

Den er nåværende versjon 3.0, som støtter Spring 4 og Java 8. Den har også plass til JSR-352, som er ny java-spesifikasjon for batchbehandling.

Her er noen interessante og praktiske brukstilfeller av rammeverket.

2. Grunnleggende om arbeidsflyt

Vårpartiet følger den tradisjonelle batcharkitekturen der et jobblager gjør jobben med å planlegge og samhandle med jobben.

En jobb kan ha mer enn ett trinn - og hvert trinn følger vanligvis sekvensen for å lese data, behandle dem og skrive dem.

Og selvfølgelig vil rammeverket gjøre det meste av det tunge løftet for oss her - spesielt når det gjelder det lave utholdenhetsarbeidet med å håndtere jobbene - ved å bruke sqlite for jobbdatabasen.

2.1. Eksempel på bruk

Den enkle bruken vi skal takle her er - vi skal migrere noen økonomiske transaksjonsdata fra CSV til XML.

Inndatafilen har en veldig enkel struktur - den inneholder en transaksjon per linje, sammensatt av: et brukernavn, bruker-ID, datoen for transaksjonen og beløpet:

brukernavn, brukerid, transaksjonsdato, transaksjonsbeløp devendra, 1234, 31/10/2015, 10000 john, 2134, 3/12/2015, 12321 robin, 2134, 2/02/2015, 23411

3. Maven POM

Avhengigheter som kreves for dette prosjektet er vårkjerne, vårparti og sqlite jdbc-kontakt:

   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

Det første vi skal gjøre er å konfigurere Spring Batch med XML:

Selvfølgelig er en Java-konfigurasjon også tilgjengelig:

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

5. Spring Batch Job Config

La oss nå skrive jobbeskrivelsen vår for CSV til XML-arbeid:

                           com.baeldung.spring_batch_intro.model.Transaction 

Og selvfølgelig, den lignende Java-baserte jobbkonfigurasjonen:

offentlig klasse SpringBatchConfig {@Autowired private JobBuilderFactory jobber; @Autowired private StepBuilderFactory trinn; @Value ("input / record.csv") privat Ressurs inputCsv; @Value ("fil: xml / output.xml") privat ressursutgangXml; @Bean public ItemReader itemReader () kaster UnexpectedInputException, ParseException {FlatFileItemReader reader = ny FlatFileItemReader (); DelimitedLineTokenizer tokenizer = ny DelimitedLineTokenizer (); String [] tokens = {"brukernavn", "brukerid", "transaksjonsdato", "beløp"}; tokenizer.setNames (tokens); reader.setResource (inputCsv); DefaultLineMapper lineMapper = ny DefaultLineMapper (); lineMapper.setLineTokenizer (tokenizer); lineMapper.setFieldSetMapper (ny RecordFieldSetMapper ()); reader.setLineMapper (lineMapper); returleser; } @Bean public ItemProcessor itemProcessor () {returner ny CustomItemProcessor (); } @Bean public ItemWriter itemWriter (Marshaller marshaller) kaster MalformedURLException {StaxEventItemWriter itemWriter = new StaxEventItemWriter (); itemWriter.setMarshaller (marshaller); itemWriter.setRootTagName ("transactionRecord"); itemWriter.setResource (outputXml); returvareWriter; } @Bean public Marshaller marshaller () {Jaxb2Marshaller marshaller = new Jaxb2Marshaller (); marshaller.setClassesToBeBound (ny klasse [] {Transaction.class}); retur marshaller; } @Bean-beskyttet trinn trinn 1 (ItemReader-leser, ItemProcessor-prosessor, ItemWriter-skribent) {return steps.get ("step1"). klump (10) .leser (leser). prosessor (prosessor). skribent (skribent) .bygg (); } @Bean (name = "firstBatchJob") offentlig jobbjobb (@Qualifier ("trinn1") trinn trinn1) {retur jobbs.get ("firstBatchJob"). Start (trinn1) .bygg (); }}

OK, så nå som vi har hele konfigurasjonen, la oss bryte den ned og begynne å diskutere den.

5.1. Les data og lag objekter med ItemReader

Først konfigurerte vi cvsFileItemReader som vil lese dataene fra record.csv og konvertere den til Transaksjon gjenstand:

@SuppressWarnings ("restriksjon") @XmlRootElement (name = "transactionRecord") offentlig klasse Transaksjon {private String brukernavn; private int userId; privat LocalDateTime transactionDate; privat dobbeltbeløp; / * getters and setters for attributtene * / @Override public String toString () {return "Transaction [username =" + username + ", userId =" + userId + ", transactionDate =" + transactionDate + ", amount =" + beløp + "]"; }}

For å gjøre det - den bruker en tilpasset kartlegger:

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

5.2. Behandler data med ItemProsessor

Vi har laget vår egen vareprosessor, CustomItemProcessor. Dette behandler ikke noe relatert til transaksjonsobjektet - alt det gjør er å overføre det opprinnelige objektet som kommer fra leseren til forfatteren:

offentlig klasse CustomItemProcessor implementerer ItemProcessor {offentlig transaksjonsprosess (transaksjonsvare) {returvare; }}

5.3. Skrive gjenstander til FS med ItemWriter

Endelig skal vi lagre dette transaksjon inn i en xml-fil som ligger på xml / output.xml:

5.4. Konfigurere batch-jobben

Så alt vi trenger å gjøre er å koble prikkene til en jobb - ved hjelp av batch: jobb syntaks.

Legg merke til forplikt-intervall - det er antall transaksjoner som skal lagres i minnet før du forplikter batchen til itemWriter; det vil holde transaksjonene i minnet til det punktet (eller til slutten av inngangsdataene oppstår):

5.5. Kjører batchjobben

Det er det - la oss nå sette opp og kjø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"); Jobbjobb = (Jobb) context.getBean ("firstBatchJob"); System.out.println ("Starter batchjobben"); prøv {JobExecution-kjøring = jobLauncher.run (jobb, nye JobParameters ()); System.out.println ("Jobbstatus:" + kjøring.getStatus ()); System.out.println ("Jobben fullført"); } fange (Unntak e) {e.printStackTrace (); System.out.println ("Jobb mislyktes"); }}}

6. Konklusjon

Denne opplæringen gir deg en grunnleggende ide om hvordan du jobber med Spring Batch og hvordan du bruker den i en enkel brukstilfelle.

Den viser hvordan du enkelt kan utvikle batchbehandlingsrørledningen din og hvordan du kan tilpasse forskjellige trinn i lesing, prosessering og skriving.

De full gjennomføring av denne opplæringen finnes i github-prosjektet - dette er et formørkelsesbasert prosjekt, så det skal være enkelt å importere og kjøre som det er.


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