Uvod u Spring Batch

1. Uvod

U ovom ćemo se članku usredotočiti na praktični uvod u Spring Batch, usredotočen na kod. Spring Batch je okvir za obradu dizajniran za robusno izvršavanje poslova.

Trenutna je verzija 3.0 koja podržava Spring 4 i Javu 8. Također sadrži JSR-352, što je nova Java specifikacija za serijsku obradu.

Evo nekoliko zanimljivih i praktičnih primjera okvira.

2. Osnove tijeka rada

Spring batch slijedi tradicionalnu batch arhitekturu gdje spremište poslova obavlja posao zakazivanja i interakcije s poslom.

Posao može imati više koraka - i svaki korak obično slijedi slijed čitanja podataka, obrade i pisanja.

I naravno da će okvir za nas ovdje učiniti većinu teškog dizanja - pogotovo kada je riječ o radu na niskim razinama upornosti pri radu - koristeći sqlite za spremište poslova.

2.1. Naš primjer upotrebe

Jednostavna upotreba koju ćemo ovdje riješiti je - migrirat ćemo neke podatke o financijskim transakcijama iz CSV-a u XML.

Ulazna datoteka ima vrlo jednostavnu strukturu - sadrži transakciju po retku koju čine: korisničko ime, korisnički ID, datum transakcije i iznos:

korisničko ime, korisničko ime, datum_ transakcije, iznos_transakcije_devendra, 1234, 31.10.2015., 10000 John, 2134, 12.3.2015., 12321 robin, 2134, 2.2.2015., 23411

3. Maven POM

Ovisnosti potrebne za ovaj projekt su jezgra opruge, šarža opruge i sqlite jdbc konektor:

   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

Prvo što ćemo učiniti jest konfigurirati Spring Batch s XML-om:

Naravno, dostupna je i Java konfiguracija:

@Configuration @EnableBatchProcessing javna klasa SpringConfig {@Value ("org / springframework / batch / core / schema-drop-sqlite.sql") private Resource dropReopsitoryTables; @Value ("org / springframework / batch / core / schema-sqlite.sql") private Resource dataReopsitorySchema; @Bean public DataSource dataSource () {DriverManagerDataSource dataSource = novi DriverManagerDataSource (); dataSource.setDriverClassName ("org.sqlite.JDBC"); dataSource.setUrl ("jdbc: sqlite: repozitorij.sqlite"); vratiti dataSource; } @Bean public DataSourceInitializer dataSourceInitializer (DataSource dataSource) baca MalformedURLException {ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator (); databasePopulator.addScript (dropReopsitoryTables); databasePopulator.addScript (dataReopsitorySchema); databasePopulator.setIgnoreFailedDrops (true); DataSourceInitializer inicijalizator = novi DataSourceInitializer (); inicijalizator.setDataSource (dataSource); Initializer.setDatabasePopulator (databasePopulator); povrat inicijalizatora; } private JobRepository getJobRepository () baca izuzetak {JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean (); factory.setDataSource (dataSource ()); factory.setTransactionManager (getTransactionManager ()); factory.afterPropertiesSet (); return (JobRepository) factory.getObject (); } private PlatformTransactionManager getTransactionManager () {return new ResourcelessTransactionManager (); } javni JobLauncher getJobLauncher () baca izuzetak {SimpleJobLauncher jobLauncher = novi SimpleJobLauncher (); jobLauncher.setJobRepository (getJobRepository ()); jobLauncher.afterPropertiesSet (); povratak jobLauncher; }}

5. Spring Batch Job Config

Napišimo sada svoj opis posla za CSV to XML rad:

                           com.baeldung.spring_batch_intro.model.Transaction 

I naravno, slična konfiguracija posla temeljena na Javi:

javna klasa SpringBatchConfig {@Autowired private JobBuilderFactory poslovi; @Automobilski privatni koraci StepBuilderFactory; @Value ("input / record.csv") privatni resurs inputCsv; @Value ("datoteka: xml / output.xml") private Resource outputXml; @Bean public ItemReader itemReader () baca UnexpectedInputException, ParseException {FlatFileItemReader reader = new FlatFileItemReader (); DelimitedLineTokenizer tokenizer = novi DelimitedLineTokenizer (); Niz [] tokeni = {"korisničko ime", "userid", "transactiondate", "iznos"}; tokenizer.setNames (tokeni); reader.setResource (inputCsv); DefaultLineMapper lineMapper = novi DefaultLineMapper (); lineMapper.setLineTokenizer (tokenizer); lineMapper.setFieldSetMapper (novi RecordFieldSetMapper ()); reader.setLineMapper (lineMapper); povratni čitač; } @Bean public ItemProcessor itemProcessor () {return new CustomItemProcessor (); } @Bean public ItemWriter itemWriter (Marshaller marshaller) baca MalformedURLException {StaxEventItemWriter itemWriter = new StaxEventItemWriter (); itemWriter.setMarshaller (marshaller); itemWriter.setRootTagName ("actionRecord "); itemWriter.setResource (outputXml); vratiti itemWriter; } @Bean public Marshaller marshaller () {Jaxb2Marshaller marshaller = novi Jaxb2Marshaller (); marshaller.setClassesToBeBound (nova klasa [] {Transaction.class}); maršal za povratak; } @Bean zaštićen korak 1 (čitač ItemReader, procesor ItemProcessor, program Writer ItemWriter) {return steps.get ("step1"). komad (10) .reader (čitač) .procesor (procesor) .writer (pisač) .build (); } @Bean (name = "firstBatchJob") javni posao posla (@Qualifier ("step1") Korak korak1) {return jobs.get ("firstBatchJob"). Start (step1) .build (); }}

U redu, sad kad imamo cijeli config, razstavimo ga i krenimo o njemu.

5.1. Čitajte podatke i stvarajte objekte pomoću Predmet za čitanje

Prvo smo konfigurirali cvsFileItemReader koji će očitavati podatke s zapis.csv i pretvoriti ga u Transakcija objekt:

@SuppressWarnings ("restrikcija") @XmlRootElement (name = "actionRecord ") javna klasa Transakcija {private String korisničko ime; private int userId; privatni LocalDateTime datum transakcije; privatni dvostruki iznos; / * getteri i postavljači za atribute * / @Override public String toString () {return "Transaction [username =" + username + ", userId =" + userId + ",actionDate =" +actionDate + ", amount =" + iznos + "]"; }}

Da bi to učinio - koristi prilagođeni mapper:

javna klasa RecordFieldSetMapper implementira FieldSetMapper {javna transakcija mapFieldSet (FieldSet fieldSet) baca BindException {DateTimeFormatter formatter = DateTimeFormatter.ofPattern ("d / M / yyy"); Transakcijska transakcija = nova Transaction (); action.setUsername (fieldSet.readString ("korisničko ime")); action.setUserId (fieldSet.readInt (1)); action.setAmount (fieldSet.readDouble (3)); String dateString = fieldSet.readString (2); action.setTransactionDate (LocalDate.parse (dateString, formatter) .atStartOfDay ()); povrat transakcije; }}

5.2. Obrada podataka pomoću PredmetProcesor

Stvorili smo vlastiti procesor predmeta, CustomItemProcessor. Ovo ne obrađuje ništa što je povezano s objektom transakcije - sve što radi je prosljeđivanje izvornog objekta koji dolazi iz čitača piscu:

javna klasa CustomItemProcessor implementira ItemProcessor {javni postupak transakcije (stavka transakcije) {return item; }}

5.3. Pisanje predmeta FS-u ItemWriter

Konačno, pohranit ćemo ovo transakcija u xml datoteku koja se nalazi na xml / output.xml:

5.4. Konfiguriranje batch zadatka

Dakle, sve što moramo učiniti je povezati točke s poslom - pomoću serija: posao sintaksa.

Napomena interval-predavanja - to je broj transakcija koje treba zadržati u memoriji prije predaje serije na itemWriter; zadržat će transakcije u memoriji do te točke (ili dok se ne nađe kraj ulaznih podataka):

5.5. Pokretanje skupnog posla

To je to - postavimo i pokrenimo sve:

aplikacija javne klase {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"); Posao posla = (Posao) context.getBean ("firstBatchJob"); System.out.println ("Pokretanje skupnog posla"); isprobajte {JobExecution Execution = jobLauncher.run (posao, novi JobParameters ()); System.out.println ("Status posla:" + izvršenje.getStatus ()); System.out.println ("Posao završen"); } catch (Iznimka e) {e.printStackTrace (); System.out.println ("Posao nije uspio"); }}}

6. Zaključak

Ovaj vam vodič daje osnovnu ideju kako raditi s Spring Batchom i kako ga koristiti u jednostavnoj upotrebi.

Pokazuje kako lako možete razviti svoj cjevovod za serijsku obradu i kako možete prilagoditi različite faze čitanja, obrade i pisanja.

The puna provedba ovog vodiča možete pronaći u projektu github - ovo je projekt zasnovan na Eclipseu, pa bi ga trebalo lako uvesti i pokrenuti kakav jest.