Η επεξεργασία παρτίδων - τυποποιημένη με μαζική προσανατολισμό, μη διαδραστική και συχνά μακροχρόνια, εκτέλεση στο παρασκήνιο - χρησιμοποιείται ευρέως σε σχεδόν κάθε κλάδο και εφαρμόζεται σε ένα ευρύ φάσμα εργασιών. Η μαζική επεξεργασία μπορεί να είναι δεδομένα ή υπολογιστικά εντατική, να εκτελείται διαδοχικά ή παράλληλα, και μπορεί να ξεκινήσει μέσω διαφόρων μοντέλων επίκλησης, συμπεριλαμβανομένων ad hoc, προγραμματισμένων και κατ 'απαίτηση.
Αυτό το σεμινάριο Spring Batch εξηγεί το μοντέλο προγραμματισμού και τη γλώσσα τομέα των εφαρμογών παρτίδας γενικά και, συγκεκριμένα, δείχνει μερικές χρήσιμες προσεγγίσεις για το σχεδιασμό και την ανάπτυξη εφαρμογών παρτίδας χρησιμοποιώντας το Άνοιξη παρτίδα 3.0.7 εκδοχή.
Τι είναι το Spring Batch;
Το Spring Batch είναι ένα ελαφρύ, περιεκτικό πλαίσιο σχεδιασμένο για να διευκολύνει την ανάπτυξη ισχυρών εφαρμογών παρτίδας. Παρέχει επίσης πιο προηγμένες τεχνικές υπηρεσίες και δυνατότητες που υποστηρίζουν εργασίες παρτίδας εξαιρετικά μεγάλου όγκου και υψηλής απόδοσης μέσω των τεχνικών βελτιστοποίησης και διαμέρισης. Το Spring Batch βασίζεται στο Με βάση το POJO αναπτυξιακή προσέγγιση του Άνοιξη πλαίσιο , οικείο σε όλους έμπειροι προγραμματιστές της Spring .
Για παράδειγμα, αυτό το άρθρο εξετάζει τον πηγαίο κώδικα από ένα δείγμα έργου που φορτώνει ένα αρχείο πελάτη με μορφή XML, φιλτράρει τους πελάτες με διάφορα χαρακτηριστικά και εξάγει τις φιλτραρισμένες καταχωρήσεις σε ένα αρχείο κειμένου. Ο πηγαίος κώδικας για το παράδειγμα Spring Batch (το οποίο χρησιμοποιεί Λομπόκ σχολιασμοί) είναι διαθέσιμος εδώ στο GitHub και απαιτεί Java SE 8 και Maven.
Είναι σημαντικό για κάθε προγραμματιστή παρτίδας να είναι εξοικειωμένος και άνετος με τις κύριες έννοιες της επεξεργασίας παρτίδας. Το παρακάτω διάγραμμα είναι μια απλοποιημένη έκδοση της αρχιτεκτονικής αναφοράς παρτίδας που έχει αποδειχθεί μέσω δεκαετιών υλοποιήσεων σε πολλές διαφορετικές πλατφόρμες. Εισάγει τις βασικές έννοιες και όρους που σχετίζονται με την επεξεργασία παρτίδας, όπως χρησιμοποιούνται από την Spring Batch.
Όπως φαίνεται στο παράδειγμα επεξεργασίας παρτίδων, μια διαδικασία παρτίδας συνήθως περικλείεται από ένα Job
αποτελούμενο από πολλαπλά Step
s. Κάθε Step
συνήθως έχει ένα | | + _ |, ItemReader
και ItemProcessor
. Α ItemWriter
εκτελείται από ένα Job
και τα μεταδεδομένα σχετικά με τις διαμορφωμένες και εκτελεσμένες εργασίες αποθηκεύονται σε ένα JobLauncher
.
Κάθε JobRepository
μπορεί να σχετίζεται με πολλαπλά Job
s, καθένα από τα οποία ορίζεται μοναδικά από το συγκεκριμένο JobInstance
που χρησιμοποιούνται για να ξεκινήσουν μια παρτίδα εργασία. Κάθε εκτέλεση ενός JobParameters
αναφέρεται ως JobInstance
. Κάθε JobExecution
συνήθως παρακολουθεί τι συνέβη κατά τη διάρκεια μιας εκτέλεσης, όπως τρέχουσες και εξερχόμενες καταστάσεις, ώρες έναρξης και λήξης κ.λπ.
Α JobExecution
είναι μια ανεξάρτητη, συγκεκριμένη φάση μιας παρτίδας Step
, έτσι ώστε κάθε Job
αποτελείται από ένα ή περισσότερα Job
s. Παρόμοια με ένα Step
, a Job
έχει ένα άτομο Step
που αντιπροσωπεύει μια μεμονωμένη προσπάθεια εκτέλεσης a StepExecution
. Step
αποθηκεύει τις πληροφορίες σχετικά με τις τρέχουσες και εξερχόμενες καταστάσεις, τις ώρες έναρξης και λήξης, και ούτω καθεξής, καθώς και αναφορές στις αντίστοιχες StepExecution
και Step
περιπτώσεις.
Ένα JobExecution
είναι ένα σύνολο ζευγών κλειδιών-τιμών που περιέχουν πληροφορίες που καλύπτονται είτε σε ExecutionContext
ή StepExecution
. Το Spring Batch παραμένει το JobExecution
, το οποίο βοηθά σε περιπτώσεις όπου θέλετε να κάνετε επανεκκίνηση μιας παρτίδας (π.χ. όταν έχει παρουσιαστεί ανεπανόρθωτο σφάλμα κ.λπ.). Το μόνο που χρειάζεται είναι να βάλετε οποιοδήποτε αντικείμενο να μοιραστείτε μεταξύ των βημάτων στο πλαίσιο και το πλαίσιο θα φροντίσει τα υπόλοιπα. Μετά την επανεκκίνηση, οι τιμές από την προηγούμενη ExecutionContext
αποκαθίστανται από τη βάση δεδομένων και εφαρμόζονται.
ExecutionContext
είναι ο μηχανισμός της Spring Batch που καθιστά δυνατή αυτή την επιμονή. Παρέχει λειτουργίες CRUD για JobRepository
, JobLauncher
, και Job
παραδείγματα. Μία φορά Step
κυκλοφορεί, a Job
λαμβάνεται από το αποθετήριο και, κατά τη διάρκεια της εκτέλεσης, JobExecution
και StepExecution
οι παρουσίες διατηρούνται στο αποθετήριο.
Ένα από τα πλεονεκτήματα του Spring Batch είναι ότι οι εξαρτήσεις του έργου είναι ελάχιστες, γεγονός που καθιστά ευκολότερη την γρήγορη ενεργοποίηση και λειτουργία. Οι λίγες εξαρτήσεις που υπάρχουν προσδιορίζονται με σαφήνεια και εξηγούνται στο JobExecution
του έργου, στο οποίο μπορείτε να έχετε πρόσβαση εδώ .
Η πραγματική εκκίνηση της εφαρμογής συμβαίνει σε μια τάξη που μοιάζει με την ακόλουθη:
pom.xml
Το @EnableBatchProcessing @SpringBootApplication public class BatchApplication { public static void main(String[] args) { prepareTestData(1000); SpringApplication.run(BatchApplication.class, args); } }
Ο σχολιασμός επιτρέπει τις λειτουργίες Spring Batch και παρέχει μια βασική διαμόρφωση για τη ρύθμιση εργασιών παρτίδας.
Το @EnableBatchProcessing
ο σχολιασμός προέρχεται από το Ανοιξιάτικη μπότα έργο που παρέχει αυτόνομες, έτοιμες για παραγωγή, εφαρμογές με βάση την άνοιξη. Καθορίζει μια κλάση διαμόρφωσης που δηλώνει ένα ή περισσότερα φασόλια Spring και επίσης ενεργοποιεί την αυτόματη διαμόρφωση και τη σάρωση στοιχείων Spring.
Το δείγμα έργου μας έχει μόνο μία εργασία που έχει διαμορφωθεί από @SpringBootApplication
με ένεση CustomerReportJobConfig
και JobBuilderFactory
. Η ελάχιστη διαμόρφωση εργασίας μπορεί να οριστεί σε StepBuilderFactory
ως εξής:
CustomerReportJobConfig
Υπάρχουν δύο βασικές προσεγγίσεις για την οικοδόμηση ενός βήματος.
Μια προσέγγιση, όπως φαίνεται στο παραπάνω παράδειγμα, είναι βασισμένη σε εργασίες . Α @Configuration public class CustomerReportJobConfig { @Autowired private JobBuilderFactory jobBuilders; @Autowired private StepBuilderFactory stepBuilders; @Bean public Job customerReportJob() { return jobBuilders.get('customerReportJob') .start(taskletStep()) .next(chunkStep()) .build(); } @Bean public Step taskletStep() { return stepBuilders.get('taskletStep') .tasklet(tasklet()) .build(); } @Bean public Tasklet tasklet() { return (contribution, chunkContext) -> { return RepeatStatus.FINISHED; }; } }
υποστηρίζει μια απλή διεπαφή που έχει μόνο μία μέθοδο, Tasklet
, η οποία καλείται επανειλημμένα έως ότου επιστρέψει execute()
ή ρίχνει μια εξαίρεση για να δείξει μια αποτυχία Κάθε κλήση στο RepeatStatus.FINISHED
είναι τυλιγμένο σε μια συναλλαγή.
Μια άλλη προσέγγιση, επεξεργασία προσανατολισμένη σε κομμάτια , αναφέρεται στην ανάγνωση των δεδομένων διαδοχικά και στη δημιουργία «τμημάτων» που θα διαγραφούν εντός ενός ορίου συναλλαγής. Κάθε μεμονωμένο στοιχείο διαβάζεται από ένα Tasklet
, παραδίδεται σε ένα ItemReader
και συγκεντρώνεται. Μόλις ο αριθμός των αντικειμένων που διαβάζονται ισούται με το διάστημα ανάληψης, ολόκληρο το κομμάτι διαγράφεται μέσω του ItemProcessor
και, στη συνέχεια, η συναλλαγή πραγματοποιείται. Ένα βήμα προσανατολισμένο στα κομμάτια μπορεί να διαμορφωθεί ως εξής:
ItemWriter
Το @Bean public Job customerReportJob() { return jobBuilders.get('customerReportJob') .start(taskletStep()) .next(chunkStep()) .build(); } @Bean public Step chunkStep() { return stepBuilders.get('chunkStep') .chunk(20) .reader(reader()) .processor(processor()) .writer(writer()) .build(); }
Η μέθοδος δημιουργεί ένα βήμα που επεξεργάζεται αντικείμενα σε κομμάτια με το μέγεθος που παρέχεται, με κάθε κομμάτι στη συνέχεια να διαβιβάζεται στον καθορισμένο αναγνώστη, επεξεργαστή και συγγραφέα. Αυτές οι μέθοδοι συζητούνται λεπτομερέστερα στις επόμενες ενότητες αυτού του άρθρου.
Για την εφαρμογή Spring Batch, για να διαβάσετε μια λίστα πελατών από ένα αρχείο XML, πρέπει να παρέχουμε μια εφαρμογή της διεπαφής chunk()
:
org.springframework.batch.item.ItemReader
Ένα public interface ItemReader { T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException; }
παρέχει τα δεδομένα και αναμένεται να είναι stateful. Συνήθως καλείται πολλές φορές για κάθε παρτίδα, με κάθε κλήση στο ItemReader
επιστρέφοντας την επόμενη τιμή και τελικά επιστρέφοντας read()
όταν όλα τα δεδομένα εισόδου έχουν εξαντληθεί.
Το Spring Batch παρέχει μερικές εξωχρηματιστηριακές υλοποιήσεις του null
, οι οποίες μπορούν να χρησιμοποιηθούν για διάφορους σκοπούς, όπως ανάγνωση συλλογών, αρχείων, ενσωμάτωσης JMS και JDBC, καθώς και πολλαπλών πηγών, και ούτω καθεξής.
Στην εφαρμογή δείγματος μας, το ItemReader
εκπρόσωποι τάξης πραγματική CustomerItemReader
καλεί σε μια τεμπέλης αρχικοποιημένη παρουσία του read()
τάξη:
IteratorItemReader
Ένα Spring bean για αυτήν την υλοποίηση δημιουργείται με το public class CustomerItemReader implements ItemReader { private final String filename; private ItemReader delegate; public CustomerItemReader(final String filename) { this.filename = filename; } @Override public Customer read() throws Exception { if (delegate == null) { delegate = new IteratorItemReader(customers()); } return delegate.read(); } private List customers() throws FileNotFoundException { try (XMLDecoder decoder = new XMLDecoder(new FileInputStream(filename))) { return (List) decoder.readObject(); } } }
και @Component
σχολιασμοί, επιτρέποντας στο Spring να γνωρίζει ότι αυτή η τάξη είναι ένα συστατικό Spring step-scoped και θα δημιουργηθεί μία φορά ανά βήμα, ως εξής:
@StepScope
@StepScope @Bean public ItemReader reader() { return new CustomerItemReader(XML_FILE); }
μετασχηματίστε στοιχεία εισαγωγής και εισαγάγετε επιχειρηματική λογική σε ένα σενάριο επεξεργασίας με γνώμονα τα στοιχεία. Πρέπει να παρέχουν μια εφαρμογή της διεπαφής ItemProcessors
:
org.springframework.batch.item.ItemProcessor
Η μέθοδος public interface ItemProcessor { O process(I item) throws Exception; }
δέχεται μία παρουσία του process()
τάξη και μπορεί ή όχι να επιστρέψει μια παρουσία του ίδιου τύπου. Επιστροφή I
υποδεικνύει ότι το αντικείμενο δεν πρέπει να συνεχίσει να υποβάλλεται σε επεξεργασία. Όπως συνήθως, η Spring παρέχει λίγους τυπικούς επεξεργαστές, όπως null
που περνά το αντικείμενο μέσω μιας ακολουθίας με ένεση CompositeItemProcessor
s και a ItemProcessor
που επικυρώνει την είσοδο.
Στην περίπτωση της εφαρμογής δείγματος, οι επεξεργαστές χρησιμοποιούνται για να φιλτράρουν πελάτες σύμφωνα με τις ακόλουθες απαιτήσεις:
Η απαίτηση «τρέχων μήνας» εφαρμόζεται μέσω ενός προσαρμοσμένου ValidatingItemProcessor
:
ItemProcessor
Η απαίτηση «περιορισμένου αριθμού συναλλαγών» εφαρμόζεται ως public class BirthdayFilterProcessor implements ItemProcessor { @Override public Customer process(final Customer item) throws Exception { if (new GregorianCalendar().get(Calendar.MONTH) == item.getBirthday().get(Calendar.MONTH)) { return item; } return null; } }
:
ValidatingItemProcessor
Αυτό το ζεύγος επεξεργαστών ενθυλακείται στη συνέχεια σε ένα public class TransactionValidatingProcessor extends ValidatingItemProcessor { public TransactionValidatingProcessor(final int limit) { super( item -> { if (item.getTransactions() >= limit) { throw new ValidationException('Customer has less than ' + limit + ' transactions'); } } ); setFilter(true); } }
που εφαρμόζει το μοτίβο του πληρεξούσιου:
CompositeItemProcessor
Για την εξαγωγή των δεδομένων, το Spring Batch παρέχει τη διεπαφή @StepScope @Bean public ItemProcessor processor() { final CompositeItemProcessor processor = new CompositeItemProcessor(); processor.setDelegates(Arrays.asList(new BirthdayFilterProcessor(), new TransactionValidatingProcessor(5))); return processor; }
για σειριοποίηση αντικειμένων όπως απαιτείται:
org.springframework.batch.item.ItemWriter
Το public interface ItemWriter { void write(List items) throws Exception; }
Η μέθοδος είναι υπεύθυνη για να βεβαιωθείτε ότι τα εσωτερικά buffer ξεπλένονται. Εάν μια συναλλαγή είναι ενεργή, συνήθως θα είναι επίσης απαραίτητο να απορρίψετε την έξοδο σε επόμενη επαναφορά. Ο πόρος στον οποίο ο συγγραφέας στέλνει δεδομένα θα πρέπει κανονικά να είναι σε θέση να το χειριστεί το ίδιο. Υπάρχουν τυπικές υλοποιήσεις όπως write()
, CompositeItemWriter
, JdbcBatchItemWriter
, JmsItemWriter
, JpaItemWriter
και άλλες.
Στην εφαρμογή δείγματός μας, η λίστα των φιλτραρισμένων πελατών γράφεται ως εξής:
SimpleMailMessageItemWriter
Από προεπιλογή, το Spring Batch εκτελεί όλες τις εργασίες που μπορεί να βρει (δηλαδή, που έχουν διαμορφωθεί όπως στο public class CustomerItemWriter implements ItemWriter, Closeable { private final PrintWriter writer; public CustomerItemWriter() { OutputStream out; try { out = new FileOutputStream('output.txt'); } catch (FileNotFoundException e) { out = System.out; } this.writer = new PrintWriter(out); } @Override public void write(final List items) throws Exception { for (Customer item : items) { writer.println(item.toString()); } } @PreDestroy @Override public void close() throws IOException { writer.close(); } }
) κατά την εκκίνηση. Για να αλλάξετε αυτήν τη συμπεριφορά, απενεργοποιήστε την εκτέλεση εργασίας κατά την εκκίνηση προσθέτοντας την ακόλουθη ιδιότητα στο CustomerReportJobConfig
:
application.properties
Ο πραγματικός προγραμματισμός επιτυγχάνεται στη συνέχεια με την προσθήκη του spring.batch.job.enabled=false
σχολιασμός σε κλάση διαμόρφωσης και το @EnableScheduling
σχολιασμός στη μέθοδο που εκτελεί την ίδια την εργασία. Ο προγραμματισμός μπορεί να διαμορφωθεί με καθυστέρηση, τιμές ή εκφράσεις cron:
@Scheduled
Υπάρχει όμως πρόβλημα με το παραπάνω παράδειγμα. Κατά το χρόνο εκτέλεσης, η εργασία θα πετύχει μόνο για πρώτη φορά. Όταν ξεκινήσει τη δεύτερη φορά (δηλ. Μετά από πέντε δευτερόλεπτα), θα δημιουργήσει τα ακόλουθα μηνύματα στα αρχεία καταγραφής (σημειώστε ότι σε προηγούμενες εκδόσεις του Spring Batch ένα // run every 5000 msec (i.e., every 5 secs) @Scheduled(fixedRate = 5000) public void run() throws Exception { JobExecution execution = jobLauncher.run( customerReportJob(), new JobParametersBuilder().toJobParameters() ); }
θα είχε ρίξει):
JobInstanceAlreadyCompleteException
Αυτό συμβαίνει επειδή μόνο μοναδικά INFO 36988 --- [pool-2-thread-1] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=customerReportJob]] launched with the following parameters: [{}] INFO 36988 --- [pool-2-thread-1] o.s.batch.core.job.SimpleStepHandler : Step already complete or not restartable, so no action to execute: StepExecution: id=1, version=3, name=taskletStep, status=COMPLETED, exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0, exitDescription= INFO 36988 --- [pool-2-thread-1] o.s.batch.core.job.SimpleStepHandler : Step already complete or not restartable, so no action to execute: StepExecution: id=2, version=53, name=chunkStep, status=COMPLETED, exitStatus=COMPLETED, readCount=1000, filterCount=982, writeCount=18 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=51, rollbackCount=0, exitDescription=
s μπορούν να δημιουργηθούν και να εκτελεστούν και το Spring Batch δεν έχει κανένα τρόπο να κάνει διάκριση μεταξύ του πρώτου και του δεύτερου JobInstance
.
Υπάρχουν δύο τρόποι αποφυγής αυτού του προβλήματος όταν προγραμματίζετε μια παρτίδα εργασία.
Πρέπει να είστε βέβαιοι ότι θα εισαγάγετε μία ή περισσότερες μοναδικές παραμέτρους (π.χ. πραγματικός χρόνος έναρξης σε νανοδευτερόλεπτα) σε κάθε εργασία:
JobInstance
Εναλλακτικά, μπορείτε να ξεκινήσετε την επόμενη εργασία με μια ακολουθία @Scheduled(fixedRate = 5000) public void run() throws Exception { jobLauncher.run( customerReportJob(), new JobParametersBuilder().addLong('uniqueness', System.nanoTime()).toJobParameters() ); }
s που καθορίζεται από το JobInstance
επισυνάπτεται στην καθορισμένη εργασία με JobParametersIncrementer
:
SimpleJobOperator.startNextInstance()
Συνήθως, για την εκτέλεση δοκιμών μονάδας σε μια εφαρμογή Spring Boot, το πλαίσιο πρέπει να φορτώνει μια αντίστοιχη @Autowired private JobOperator operator; @Autowired private JobExplorer jobs; @Scheduled(fixedRate = 5000) public void run() throws Exception { List lastInstances = jobs.getJobInstances(JOB_NAME, 0, 1); if (lastInstances.isEmpty()) { jobLauncher.run(customerReportJob(), new JobParameters()); } else { operator.startNextInstance(JOB_NAME); } }
. Για αυτό το σκοπό χρησιμοποιούνται δύο σχολιασμοί:
ApplicationContext
Υπάρχει τάξη χρησιμότητας @RunWith(SpringRunner.class) @ContextConfiguration(classes = {...})
για δοκιμή παρτίδων. Παρέχει μεθόδους για την έναρξη μιας ολόκληρης εργασίας, καθώς και τη δυνατότητα δοκιμής μεμονωμένων βημάτων από άκρο σε άκρο χωρίς να χρειάζεται να εκτελείτε κάθε βήμα της εργασίας. Πρέπει να δηλωθεί ως φασόλι άνοιξη:
org.springframework.batch.test.JobLauncherTestUtils
Ένα τυπικό τεστ για μια δουλειά και ένα βήμα φαίνεται ως εξής (και μπορεί να χρησιμοποιήσει και πλαστά πλαίσια):
@Configuration public class BatchTestConfiguration { @Bean public JobLauncherTestUtils jobLauncherTestUtils() { return new JobLauncherTestUtils(); } }
Το Spring Batch εισάγει πρόσθετα περιθώρια για βήματα και εργασιακά περιβάλλοντα. Τα αντικείμενα σε αυτά τα πεδία χρησιμοποιούν το Spring container ως εργοστάσιο αντικειμένων, οπότε υπάρχει μόνο μία παρουσία κάθε τέτοιου φασολιού ανά βήμα εκτέλεσης ή εργασία. Επιπλέον, παρέχεται υποστήριξη για καθυστερημένη δέσμευση αναφορών που είναι προσβάσιμες από το @RunWith(SpringRunner.class) @ContextConfiguration(classes = {BatchApplication.class, BatchTestConfiguration.class}) public class CustomerReportJobConfigTest { @Autowired private JobLauncherTestUtils testUtils; @Autowired private CustomerReportJobConfig config; @Test public void testEntireJob() throws Exception { final JobExecution result = testUtils.getJobLauncher().run(config.customerReportJob(), testUtils.getUniqueJobParameters()); Assert.assertNotNull(result); Assert.assertEquals(BatchStatus.COMPLETED, result.getStatus()); } @Test public void testSpecificStep() { Assert.assertEquals(BatchStatus.COMPLETED, testUtils.launchStep('taskletStep').getStatus()); } }
ή StepContext
. Τα στοιχεία που έχουν διαμορφωθεί κατά το χρόνο εκτέλεσης ώστε να είναι κλιμακωτά ή με εύρος εργασίας είναι δύσκολο να ελεγχθούν ως αυτόνομα συστατικά, εκτός εάν έχετε έναν τρόπο να ρυθμίσετε το περιβάλλον σαν να ήταν σε ένα βήμα ή σε εκτέλεση εργασίας. Αυτός είναι ο στόχος του JobContext
και org.springframework.batch.test.StepScopeTestExecutionListener
εξαρτήματα στο Spring Batch, καθώς και org.springframework.batch.test.StepScopeTestUtils
και JobScopeTestExecutionListener
.
Το JobScopeTestUtils
δηλώνονται σε επίπεδο τάξης και η δουλειά του είναι να δημιουργήσει ένα πλαίσιο εκτέλεσης βημάτων για κάθε μέθοδο δοκιμής. Για παράδειγμα:
TestExecutionListeners
Υπάρχουν δύο @RunWith(SpringRunner.class) @TestExecutionListeners({DependencyInjectionTestExecutionListener.class, StepScopeTestExecutionListener.class}) @ContextConfiguration(classes = {BatchApplication.class, BatchTestConfiguration.class}) public class BirthdayFilterProcessorTest { @Autowired private BirthdayFilterProcessor processor; public StepExecution getStepExecution() { return MetaDataInstanceFactory.createStepExecution(); } @Test public void filter() throws Exception { final Customer customer = new Customer(); customer.setId(1); customer.setName('name'); customer.setBirthday(new GregorianCalendar()); Assert.assertNotNull(processor.process(customer)); } }
s. Το ένα είναι από το κανονικό πλαίσιο Spring Test και χειρίζεται την έγχυση εξάρτησης από το διαμορφωμένο περιβάλλον εφαρμογής. Το άλλο είναι το Spring Batch TestExecutionListener
που ρυθμίζει το πλαίσιο-βήμα για την εξάρτηση της έγχυσης σε δοκιμές μονάδας. Α StepScopeTestExecutionListener
δημιουργείται για όλη τη διάρκεια μιας μεθόδου δοκιμής και διατίθεται σε όλες τις εξαρτήσεις που εισάγονται. Η προεπιλεγμένη συμπεριφορά είναι απλώς η δημιουργία ενός StepContext
με σταθερές ιδιότητες. Εναλλακτικά, το StepExecution
μπορεί να παρέχεται από τη δοκιμαστική θήκη ως εργοστασιακή μέθοδο που επιστρέφει τον σωστό τύπο.
Μια άλλη προσέγγιση βασίζεται στο StepContext
τάξη χρησιμότητας. Αυτή η τάξη χρησιμοποιείται για τη δημιουργία και τον χειρισμό StepScopeTestUtils
σε δοκιμές μονάδας με πιο ευέλικτο τρόπο χωρίς χρήση έγχυσης εξάρτησης. Για παράδειγμα, η ανάγνωση του αναγνωριστικού του πελάτη που φιλτράρεται από τον παραπάνω επεξεργαστή θα μπορούσε να γίνει ως εξής:
StepScope
Αυτό το άρθρο παρουσιάζει μερικά από τα βασικά στοιχεία του σχεδιασμού και της ανάπτυξης εφαρμογών Spring Batch. Ωστόσο, υπάρχουν πολλά πιο προηγμένα θέματα και δυνατότητες - όπως κλιμάκωση, παράλληλη επεξεργασία, ακροατές και άλλα - που δεν αναφέρονται σε αυτό το άρθρο. Ας ελπίσουμε ότι αυτό το άρθρο παρέχει μια χρήσιμη βάση για να ξεκινήσετε.
Στη συνέχεια μπορείτε να βρείτε πληροφορίες για αυτά τα πιο προηγμένα θέματα επίσημη τεκμηρίωση Spring Back για Spring Batch.
Το Spring Batch είναι ένα ελαφρύ, περιεκτικό πλαίσιο σχεδιασμένο για να διευκολύνει την ανάπτυξη ισχυρών εφαρμογών παρτίδας. Παρέχει επίσης πιο προηγμένες τεχνικές υπηρεσίες και δυνατότητες που υποστηρίζουν εργασίες παρτίδας εξαιρετικά μεγάλου όγκου και υψηλής απόδοσης μέσω των τεχνικών βελτιστοποίησης και διαμέρισης.
Το «Βήμα» είναι μια ανεξάρτητη, συγκεκριμένη φάση μιας παρτίδας «Εργασία», έτσι ώστε κάθε Εργασία να αποτελείται από ένα ή περισσότερα Βήματα.
Το «JobRepository» είναι ο μηχανισμός του Spring Batch που καθιστά δυνατή αυτή την επιμονή. Παρέχει λειτουργίες CRUD για λειτουργίες JobLauncher, Job και Step.
Μια προσέγγιση βασίζεται σε tasklet, όπου ένα Tasklet υποστηρίζει μια απλή διεπαφή με μία μέθοδο εκτέλεσης (). Η άλλη προσέγγιση, ** επεξεργασία προσανατολισμένων σε κομμάτια **, αναφέρεται στην ανάγνωση των δεδομένων διαδοχικά και στη δημιουργία «τμημάτων» που θα διαγραφούν εντός ενός ορίου συναλλαγής.