Tavaszi tétel - Feladatok vs darabok
1. Bemutatkozás
A Spring Batch két különböző módot kínál a munka megvalósítására: a tasklet és a darabokat.
Ebben a cikkben megtudhatjuk, hogyan kell konfigurálni és megvalósítani mindkét módszert egy egyszerű valós példával.
2. Függőségek
Kezdjük azzal a szükséges függőségek hozzáadása:
org.springframework.batch spring-batch-core 4.2.0.RELEASE org.springframework.batch spring-batch-test 4.2.0.RELEASE test
A rugós kötegelt mag és a rugós köteg teszt legújabb verziójának beszerzéséhez olvassa el a Maven Central oldalt.
3. Felhasználási esetünk
Vegyünk egy CSV-fájlt a következő tartalommal:
Mae Hodges, 1972/22/22 Gary Potter, 1953/02/22 Betty Wise, 1968/02/17 Wayne Rose, 1977/06/04 Adam Caldwell, 1995/09/27 Lucille Phillips, 1992/14/14
A Minden sor első pozíciója egy személy nevét, a második pozíció pedig a születési dátumát jelöli.
Felhasználási esetünk az hozzon létre egy másik CSV fájlt, amely tartalmazza az egyes személyek nevét és életkorát:
Mae Hodges, 45 Gary Potter, 64 Betty Wise, 49 Wayne Rose, 40 Adam Caldwell, 22 Lucille Phillips, 25
Most, hogy a tartományunk tiszta, menjünk tovább, és készítsünk egy megoldást mindkét megközelítés segítségével. Kezdjük a tasklettel.
4. Feladatok megközelítése
4.1. Bevezetés és tervezés
A feladatok egyetlen feladat végrehajtását jelentik egy lépésen belül. Munkánk több lépésből áll, amelyek egymás után hajtanak végre. Minden lépésnek csak egy meghatározott feladatot kell végrehajtania.
Munkánk három lépésből áll:
- Sorok olvasása a bemeneti CSV fájlból.
- Számítsa ki a bemeneti CSV-fájlban szereplő személyek életkorát.
- Írja be minden személy nevét és életkorát egy új kimeneti CSV fájlba.
Most, hogy elkészült az összkép, hozzunk létre egy osztályt lépésenként.
LinesReader feladata lesz az adatok beolvasása a bemeneti fájlból:
public class LinesReader megvalósítja a Taskletet {// ...}
LinesProcessor kiszámítja a fájlban szereplő személyek életkorát:
public class LinesProcessor megvalósítja a Taskletet {// ...}
Végül, LinesWriter feladata lesz neveket és életkorokat kimeneti fájlba írni:
public class LinesWriter megvalósítja a Taskletet {// ...}
Ezen a ponton, minden lépésünk megvalósul Feladat felület. Ez arra kényszerít minket, hogy megvalósítsuk végrehajtani módszer:
@Orride public RepeatStatus execute (StepContribution stepContribution, ChunkContext chunkContext) dobja a kivételt {// ...}
Ebben a módszerben adjuk hozzá az egyes lépések logikáját. Mielőtt ezzel a kóddal kezdjük, konfiguráljuk a munkánkat.
4.2. Konfiguráció
Meg kell adjon hozzá néhány konfigurációt a Spring alkalmazáskörnyezetéhez. Az előző szakaszban létrehozott osztályok standard babdeklarációjának hozzáadása után készen állunk a feladatmeghatározásunk létrehozására:
@Configuration @EnableBatchProcessing public class TaskletsConfig {@Autowired private JobBuilderFactory jobs; @Autowired private StepBuilderFactory lépések; @Bean védett lépés readLines () {visszatérési lépések .get ("readLines") .tasklet (linesReader ()) .build (); } @Bean védett lépés processLines () {return steps .get ("processLines") .tasklet (linesProcessor ()) .build (); } @Bean védett lépés írási sorok () {visszatérési lépések .get ("writeLines") .tasklet (linesWriter ()) .build (); } @Bean public job job () {munkahelyek visszaadása .get ("taskletsJob") .start (readLines ()) .next (processLines ()) .next (writeLines ()) .build (); } // ...}
Ez azt jelenti, hogy a mi „TaskletsJob” három lépésből áll. Az első (readLines) végrehajtja a babban definiált feladatlapot linesReader és lépjen a következő lépésre: processLines. ProcessLines végrehajtja a babban definiált feladatlapot vonalakProcesszor és folytassa az utolsó lépéssel: writeLines.
Munkafolyamatunk meg van határozva, és készen állunk a logika hozzáadására!
4.3. Modell és segédprogramok
Mivel egy CSV-fájl sorait fogjuk manipulálni, létrehozunk egy osztályt Vonal:
public class Line megvalósítja a Serializable {private String name; magán LocalDate dob; magán Hosszú életkor; // standard konstruktor, getterek, beállítók és toString implementáció}
Kérjük, vegye figyelembe, hogy Vonal megvalósítja Sorosítható. Ez azért van, mert Vonal DTO-ként fog működni az adatok átvitele a lépések között. A Spring Batch szerint a lépések között átvitt objektumoknak sorosíthatóknak kell lenniük.
Másrészt elkezdhetünk gondolkodni a sorok olvasásán és írásán.
Ehhez felhasználjuk az OpenCSV-t:
com.opencsv opencsv 4.1
Keresse meg a legújabb OpenCSV verziót a Maven Central-ban.
Miután az OpenCSV bekerült, létrehozunk egy FileUtils osztály. Meg fogja adni a CSV-vonalak olvasási és írási módszereit:
public class FileUtils {public line readLine () dobja a Kivételt {if (CSVReader == null) initReader (); Karakterlánc [] sor = CSVReader.readNext (); if (line == null) return null; return new Line (sor [0], LocalDate.parse (sor [1], DateTimeFormatter.ofPattern ("HH / nn / éééé"))); } public void writeLine (Vonal) dobja a (z) {if (CSVWriter == null) initWriter () kivételt; Karakterlánc [] lineStr = új karakterlánc [2]; lineStr [0] = line.getName (); lineStr [1] = line .getAge () .toString (); CSVWriter.writeNext (lineStr); } // ...}
Figyelje meg readLine burkolóként működik az OpenCSV-k felett readNext metódus és visszatér a Vonal tárgy.
Ugyanilyen módon, writeLine becsomagolja az OpenCSV-ket writeNext fogadó a Vonal tárgy. Ennek az osztálynak a teljes megvalósítása megtalálható a GitHub Projektben.
Ezen a ponton mindannyian készen állunk az egyes lépések megvalósításának megkezdésére.
4.4. LinesReader
Menjünk előre, és fejezzük be a dolgunkat LinesReader osztály:
public class LinesReader végrehajtja a Tasklet, StepExecutionListener {private final Logger logger = LoggerFactory .getLogger (LinesReader.class); privát List sorok; privát FileUtils fu; @Orride public void beforeStep (StepExecution stepExecution) {lines = new ArrayList (); fu = new FileUtils ("taskletsvschunks / input / tasklets-vs-chunks.csv"); logger.debug ("A Vonal olvasó inicializálva."); } @Override public RepeatStatus execute (StepContribution stepContribution, ChunkContext chunkContext) dobja a Kivételt {Line line = fu.readLine (); while (vonal! = null) {sorok.add (vonal); logger.debug ("Olvasási sor:" + line.toString ()); vonal = fu.readLine (); } return RepeatStatus.FINISHED; } @Orride public ExitStatus afterStep (StepExecution stepExecution) {fu.closeReader (); stepExecution .getJobExecution () .getExecutionContext () .put ("vonalak", ez.sorok); logger.debug ("A Vonal olvasó véget ért."); return ExitStatus.COMPLETED; }}
A LinesReader végrehajtja módszer létrehozza a FileUtils példány a bemeneti fájl elérési útján. Azután, sorokat ad hozzá a listához, amíg nincs több olvasnivaló sor.
Az óránk megvalósítja is StepExecutionListener amely két extra módszert kínál: előttStep és afterStep. Ezekkel a módszerekkel inicializáljuk és lezárjuk a dolgokat előtte és utána végrehajtani fut.
Ha megnézzük afterStep kódot, észrevesszük azt a sort, ahol az eredménylista (vonalak) a munka kontextusába kerül, hogy elérhetővé váljon a következő lépéshez:
stepExecution .getJobExecution () .getExecutionContext () .put ("vonalak", ez.sorok);
Ezen a ponton első lépésünk már eleget tett felelősségének: töltsön be CSV-vonalakat a Lista emlékül. Térjünk át a második lépésre és dolgozzuk fel őket.
4.5. LinesProcessor
LinesProcessor megvalósítani is fogja StepExecutionListener és természetesen, Feladat. Ez azt jelenti, hogy megvalósítja előttStep, végrehajtani és afterStep módszerek is:
public class LinesProcessor megvalósítja a Tasklet, StepExecutionListener {private Logger logger = LoggerFactory.getLogger (LinesProcessor.class); privát List sorok; @Orride public void beforeStep (StepExecution stepExecution) {ExecutionContext végrehajtásiContext = stepExecution .getJobExecution () .getExecutionContext (); this.lines = (List) végrehajtásContext.get ("vonalak"); logger.debug ("A vonalak processzora inicializálva."); } @Orride public RepeatStatus execute (StepContribution stepContribution, ChunkContext chunkContext) dobja a Kivételt {for (Line line: lines) {long age = ChronoUnit.YEARS.between (line.getDob (), LocalDate.now ()); logger.debug ("Számított életkor" + életkor + "sor" + line.toString ()); line.setAge (életkor); } return RepeatStatus.FINISHED; } @Orride public ExitStatus afterStep (StepExecution stepExecution) {logger.debug ("A vonalak processzora leállt."); return ExitStatus.COMPLETED; }}
Könnyű ezt megérteni betölti vonalak listázzon a munkakörnyezetből, és kiszámolja az egyes emberek életkorát.
Nem szükséges újabb eredménylistát a kontextusba helyezni, mivel a módosítások ugyanazon az objektumon történnek, mint az előző lépésből.
És készen állunk az utolsó lépésünkre.
4.6. LinesWriter
LinesWriterFeladata, hogy átmenjen vonalak listázza és írja be a nevet és az életkort a kimeneti fájlba:
public class LinesWriter megvalósítja a Tasklet, StepExecutionListener {private final Logger logger = LoggerFactory .getLogger (LinesWriter.class); privát List sorok; privát FileUtils fu; @Orride public void beforeStep (StepExecution stepExecution) {ExecutionContext végrehajtásiContext = stepExecution .getJobExecution () .getExecutionContext (); this.lines = (List) végrehajtásContext.get ("vonalak"); fu = new FileUtils ("output.csv"); logger.debug ("A vonalak írója inicializálva."); } @Override public RepeatStatus execute (StepContribution stepContribution, ChunkContext chunkContext) dobja a Kivételt {for (Line line: lines) {fu.writeLine (line); logger.debug ("Írta a sort" + line.toString ()); } return RepeatStatus.FINISHED; } @Override public ExitStatus afterStep (StepExecution stepExecution) {fu.closeWriter (); logger.debug ("A vonalak írójának vége."); return ExitStatus.COMPLETED; }}
Befejeztük munkánk megvalósítását! Hozzunk létre egy tesztet a futtatásához és az eredmények megtekintéséhez.
4.7. A munka futtatása
A feladat futtatásához létrehozunk egy tesztet:
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (class = TaskletsConfig.class) public class TaskletsTest {@Autowired private JobLauncherTestUtils jobLauncherTestUtils; @Test public void givenTaskletsJob_whenJobEnds_thenStatusCompleted () dobja a Kivételt {JobExecution jobExecution = jobLauncherTestUtils.launchJob (); assertEquals (ExitStatus.COMPLETED, jobExecution.getExitStatus ()); }}
ContextConfiguration az annotáció a Spring kontextus konfigurációs osztályra mutat, amely megadja a munkánk definícióját.
A teszt futtatása előtt hozzá kell adnunk néhány extra babot:
@Bean public JobLauncherTestUtils jobLauncherTestUtils () {return new JobLauncherTestUtils (); } @Bean public JobRepository jobRepository () dobja a Kivételt {MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean (); factory.setTransactionManager (tranzakcióManager ()); return (JobRepository) factory.getObject (); } @Bean public PlatformTransactionManageractionManager () {return new ResourcelessTransactionManager (); } @Bean public JobLauncher jobLauncher () dobja a Kivételt {SimpleJobLauncher jobLauncher = új SimpleJobLauncher (); jobLauncher.setJobRepository (jobRepository ()); return jobLauncher; }
Minden készen áll! Folytasd és futtasd a tesztet!
A munka befejezése után output.csv a várt tartalom és a naplók megmutatják a végrehajtási folyamatot:
[main] DEBUG o.b.t.tasklets.LinesReader - Lines Reader inicializálva. [main] DEBUG obttasklets.LinesReader - Sor olvasása: [Mae Hodges, 1972.10.22.] [main] DEBUG obttasklets.LinesReader - Read line: [Gary Potter, 1953.02.22.] [main] DEBUG obttasklets .LinesReader - Olvasd el a sort: [Betty Wise, 1968.02.17.] [Main] DEBUG obttasklets.LinesReader - Read line: [Wayne Rose, 1977.06.04.] [Main] DEBUG obttasklets.LinesReader - Sor olvasása: [Adam Caldwell, 1995. 09. 27.] [main] DEBUG obttasklets.LinesReader - Read read: [Lucille Phillips, 1992.05.14.] [Main] DEBUG obttasklets.LinesReader - Lines Reader véget ért. [main] DEBUG o.b.t.tasklets.LinesProcessor - Lines processzor inicializálva. [main] DEBUG obttasklets.LinesProcessor - Számított 45 éves kor [Mae Hodges, 1972.10.22.] [main] DEBUG obttasklets.LinesProcessor - Számított életkor 64 vonal [Gary Potter, 1952.02.22.] [fő ] DEBUG obttasklets.LinesProcessor - Számított 49 éves kor [Betty Wise, 1968.02.17.] [Main] DEBUG obttasklets.LinesProcessor - Számított 40 éves kor [Wayne Rose, 1977.06.06.] [Main] DEBUG obttasklets.LinesProcessor - Számított életkor 22 vonalra [Adam Caldwell, 1995/09/27] [main] DEBUG obttasklets.LinesProcessor - Számított életkor 25 vonalra [Lucille Phillips, 1992/14/14] [main] DEBUG obttasklet .LinesProcessor - A Lines Processor leállt. [main] DEBUG o.b.t.tasklets.LinesWriter - Lines Writer inicializálva. [main] DEBUG obttasklets.LinesWriter - Írta a sort [Mae Hodges, 1972.10.22., 45.] [main] DEBUG obttasklets.LinesWriter - Írta a sort [Gary Potter, 1953.02.22., 64] [main] DEBUG obttasklets.LinesWriter - Írta a sort [Betty Wise, 1968.02.17., 49] [main] DEBUG obttasklets.LinesWriter - Írta a sort [Wayne Rose, 1977. 06. 06. 40] [main] DEBUG obttasklets.LinesWriter - Írta a sort [Adam Caldwell, 1995/09/27, 22] [main] DEBUG obttasklets.LinesWriter - Írta a sort [Lucille Phillips, 1992/14 / 14,25] [main] DEBUG obttasklets.LinesWriter - Lines Writer véget ért .
Ennyi a Taskleteknek. Most áttérhetünk a Chunks megközelítésre.
5. Darabok megközelítése
5.1. Bevezetés és tervezés
Ahogy a neve is sugallja, ez a megközelítés műveleteket hajt végre az adatcsomók felett. Vagyis ahelyett, hogy minden sort egyszerre olvasna, feldolgozna és írna, egyszerre rögzített mennyiségű rekordot (darabokat) fog olvasni, feldolgozni és írni.
Ezután megismétli a ciklust, amíg nincs több adat a fájlban.
Ennek eredményeként az áramlás kissé eltér:
- Amíg vannak sorok:
- X mennyiségű sor esetén tegye:
- Olvasson el egy sort
- Feldolgozzon egy sort
- Írjon X sort.
- X mennyiségű sor esetén tegye:
Tehát nekünk is alkotnunk kell három bab a daraborientált megközelítéshez:
nyilvános osztály LineReader {// ...}
nyilvános osztály LineProcessor {// ...}
public class LinesWriter {// ...}
Mielőtt áttérne a megvalósításra, konfiguráljuk a munkánkat.
5.2. Konfiguráció
A munkakör meghatározása is másképp fog kinézni:
@Configuration @EnableBatchProcessing public class ChunksConfig {@Autowired private JobBuilderFactory jobs; @Autowired private StepBuilderFactory lépések; @Bean public ItemReader itemReader () {return new LineReader (); } @Bean public ItemProcessor itemProcessor () {return new LineProcessor (); } @Bean public ItemWriter itemWriter () {return new LinesWriter (); } @Bean védett lépés processLines (ItemReader olvasó, ItemProcessor processzor, ItemWriter író) {return steps.get ("processLines"). darab (2) .olvasó (olvasó) .processzor (processzor) .író (író) .build (); } @Bean public job job () {munkahelyek visszaadása .get ("chunksJob") .start (processLines (itemReader (), itemProcessor (), itemWriter ())) .build (); }}
Ebben az esetben csak egy lépés van, és csak egy feladatfüzetet hajt végre.
Azonban az a feladatlap meghatározza az olvasókat, az írókat és a processzorokat, amelyek az adatok darabjaira hatnak.
Vegye figyelembe, hogy a a végrehajtási intervallum az egy darabban feldolgozandó adatmennyiséget jelzi. A munkánk egyszerre két sort fog olvasni, feldolgozni és írni.
Most készen állunk a darabos logikánk hozzáadására!
5.3. LineReader
LineReader feladata lesz egy lemez elolvasása és a Vonal például a tartalmával.
Olvasóvá válni, osztályunknak végre kell hajtania ItemReader felület:
public class LineReader megvalósítja a ItemReader {@Orride public line read () dobja a Kivételt {Line line = fu.readLine (); if (line! = null) logger.debug ("Olvasd el a sort:" + line.toString ()); visszatérő vonal; }}
A kód egyértelmű, csak egy sort olvas és visszaadja. Meg is valósítjuk StepExecutionListener az osztály végleges változatához:
public class LineReader megvalósítja a ItemReader, StepExecutionListener {private final Logger logger = LoggerFactory .getLogger (LineReader.class); privát FileUtils fu; @Orride public void beforeStep (StepExecution stepExecution) {fu = new FileUtils ("taskletsvschunks / input / tasklets-vs-chunks.csv"); logger.debug ("A vonalas olvasó inicializálva."); } @Orride public Line read () dobja a {Line line = fu.readLine () kivételt; if (line! = null) logger.debug ("Olvasd el a sort:" + line.toString ()); visszatérő vonal; } @Orride public ExitStatus afterStep (StepExecution stepExecution) {fu.closeReader (); logger.debug ("Véget ért a sorolvasó."); return ExitStatus.COMPLETED; }}
Ezt észre kell venni beforeStep és afterStep végre kell hajtani az egész lépés előtt, illetve után.
5.4. LineProcessor
LineProcessor nagyjából ugyanazt a logikát követi, mint LineReader.
Ebben az esetben azonban megvalósítjuk ItemProcessor és annak módszere folyamat():
public class LineProcessor megvalósítja az ItemProcessor {private Logger logger = LoggerFactory.getLogger (LineProcessor.class); A @Orride public line process (Line line) kivételt dob a {long age = ChronoUnit.YEARS. Között (line.getDob (), LocalDate.now ()); logger.debug ("Számított életkor" + életkor + "sor" + line.toString ()); line.setAge (életkor); visszatérő vonal; }}
A folyamat() A method felvesz egy beviteli sort, feldolgozza és kimeneti sort ad vissza. Ismét megvalósítjuk StepExecutionListener:
public class LineProcessor megvalósítja az ItemProcessor, StepExecutionListener {private Logger logger = LoggerFactory.getLogger (LineProcessor.class); @Orride public void beforeStep (StepExecution stepExecution) {logger.debug ("A vonal processzor inicializálva."); } @Orride public line process (Line line) dobja a {long age = ChronoUnit.YEARS. Kivétel (line.getDob (), LocalDate.now ()) kivételt; logger.debug ("Számított életkor" + életkor + "sor" + line.toString ()); line.setAge (életkor); visszatérő vonal; } @Orride public ExitStatus afterStep (StepExecution stepExecution) {logger.debug ("A vonalprocesszor leállt."); return ExitStatus.COMPLETED; }}
5.5. LinesWriter
Az olvasóval és a processzorral ellentétben LinesWriter egy egész sort fog írni hogy megkapja a Lista nak,-nek Vonalak:
public class LinesWriter megvalósítja a ItemWriter, StepExecutionListener {private final Logger logger = LoggerFactory .getLogger (LinesWriter.class); privát FileUtils fu; @Orride public void beforeStep (StepExecution stepExecution) {fu = new FileUtils ("output.csv"); logger.debug ("A vonalkód inicializálva."); } @Orride public void write (Sorok felsorolása) dobja a Kivételt {a (Vonal: sorok) {fu.writeLine (sor); logger.debug ("Írta a sort" + line.toString ()); }} @Override public ExitStatus afterStep (StepExecution stepExecution) {fu.closeWriter (); logger.debug ("A vonalkód leállt."); return ExitStatus.COMPLETED; }}
LinesWriter kód önmagáért beszél. És ismét készen állunk a munkánk tesztelésére.
5.6. A munka futtatása
Létrehozunk egy új tesztet, amelyet a tasklets megközelítéshez készítettünk:
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (class = ChunksConfig.class) public class ChunksTest {@Autowired private JobLauncherTestUtils jobLauncherTestUtils; @Test public void givenChunksJob_whenJobEnds_thenStatusCompleted () dobja a Kivételt {JobExecution jobExecution = jobLauncherTestUtils.launchJob (); assertEquals (ExitStatus.COMPLETED, jobExecution.getExitStatus ()); }}
Konfigurálás után ChunksConfig amint azt fentebb kifejtettük TaskletsConfig, mindannyian készen állunk a teszt futtatására!
A munka elvégzése után ezt láthatjuk output.csv ismét tartalmazza a várt eredményt, és a naplók leírják a folyamatot:
[main] DEBUG o.b.t.chunks.LineReader - A sorolvasó inicializálva van. [main] DEBUG o.b.t.chunks.LinesWriter - A vonalkód inicializálva van. [main] DEBUG o.b.t.chunks.LineProcessor - Vonalfeldolgozó inicializálva. [main] DEBUG obtchunks.LineReader - Olvasd el a sort: [Mae Hodges, 1972.10.10.] [main] DEBUG obtchunks.LineReader - Olvasd a sort: [Gary Potter, 1953.02.22.] [main] DEBUG obtchunks .LineProcessor - Számított 45 éves kor [Mae Hodges, 1972.10.22.] [Main] DEBUG obtchunks.LineProcessor - Számított életkor 64 vonal [Gary Potter, 1953.02.22.] [Main] DEBUG obtchunks.LinesWriter - Írta a sort [Mae Hodges, 1972.10.22., 45] [main] DEBUG obtchunks.LinesWriter - Írta a sort [Gary Potter, 1953.02.22., 64] [main] DEBUG obtchunks.LineReader - Sor olvasása: [Betty Wise, 1968.02.17.] [Main] DEBUG obtchunks.LineReader - Read read: [Wayne Rose, 1977.06.04.] [Main] DEBUG obtchunks.LineProcessor - 49-es számított életkor [Betty Wise, 1968.02.17.] [Main] DEBUG obtchunks.LineProcessor - 40 éves életkor kiszámítása [Wayne Rose, 1977.06.04.] [Main] DEBUG obtchunks.LinesWriter - Sor írása [Betty Wise, 1968.02.17. , 49] [main] DEBUG obtchunks.LinesWriter - Sorot írt [Wayne Rose, 1977.06.06., 40] [main] DEBUG ob t.chunks.LineReader - Olvasd el a sort: [Adam Caldwell, 1995. 09. 27.] [main] DEBUG obtchunks.LineReader - Read line: [Lucille Phillips, 1992.05.14.] [main] DEBUG obtchunks.LineProcessor - Számított 22 éves kor a vonalon [Adam Caldwell, 09/27/1995] [main] DEBUG obtchunks.LineProcessor - Számított 25 éves kor a vonalon [Lucille Phillips, 05/14/1992] [main] DEBUG obtchunks.LinesWriter - Írta a sort [Adam Caldwell, 1995/09/27, 22] [main] DEBUG obtchunks.LinesWriter - Írta a sort [Lucille Phillips, 1992.05.14., 25] [main] DEBUG obtchunks.LineProcessor - Vonalfeldolgozó lejárt. [main] DEBUG o.b.t.chunks.LinesWriter - A Line Writer befejeződött. [main] DEBUG o.b.t.chunks.LineReader - Véget ért a sorolvasó.
Ugyanaz az eredményünk és más az áramlásunk. A naplók nyilvánvalóvá teszik a feladat végrehajtását ennek a megközelítésnek megfelelően.
6. Következtetés
Különböző összefüggések mutatják be az egyik vagy másik megközelítés szükségességét. Míg a Tasklet természetesebbnek érzi az „egyik a másik után a feladatot” forgatókönyveket, a darabok egyszerű megoldást kínálnak a lapozott olvasások vagy olyan helyzetek kezelésére, amikor nem akarunk jelentős mennyiségű adatot a memóriában tartani.
Ennek a példának a teljes megvalósítása megtalálható a a GitHub projekt.