Spring Batch 2.1 – Ein kleiner Migrationsguide

Keine Kommentare

In meinem letzten Blogeintrag habe ich bewusst die alte Spring Batch Version 1.x als Grundlage für das Beispiel genommen. Meine Erfahrungen haben gezeigt, dass diese Version noch häufig zum Einsatz kommt. In diesem Beitrag möchte ich einen kleinen Überblick über die Änderungen geben und zeigen, dass der Wechsel auf die neue Version 2.1 gar nicht so aufwändig ist und man dadurch viele Vorteile hat.

Migration

Zunächst einmal fällt auf, dass die Job-Konfiguration durch den neuen Batch-Namespace deutlich lesbarer ist. Es lässt sich aus meiner Sicht viel einfacher und schneller die Grundstruktur erfassen. Die Angabe der fatal-exception-classes entfällt, da nun mit include-exclude-Filtern gearbeitet wird. Neben den skippable-exception-classes können noch retryable-exception-classes definiert werden. Im Vergleich zum springframework in der Version 3 ist Spring Batch nicht abwärtskompatibel, so dass bestehende Konfigurationen nicht mehr verwendet werden können. Zusätzlich haben sich auch einige Änderungen am Datenbank-Schema ergeben. Dies stellt aber normalerweise kein Problem dar, da eine Migration der Job-Daten nicht notwendig sein sollte.

In der alten Version wurde als Standard eine item-orientierte Verarbeitung verwendet. Neu ist nun die Zusammenfassung von 1-n items zu einem chunk. Daraus ergibt sich der Vorteil, dass alle Items, die zu einer Transaktion gehören (commit-interval) als Paket an den ItemWriter gereicht werden. Der Entwickler braucht nun nicht mehr die Methoden mark, reset, flush, and clear implementieren, da die Rollback-Logik nun vom Framework selbst übernommen wird.

<job id="flatFileJob" parent="simpleJob" xmlns="http://www.springframework.org/schema/batch">
    <step id="step1" next="step2">    
        <tasklet>            
            <chunk reader="fileItemReader" writer="itemWriter" commit-interval="5" skip-limit="100">
                <streams>
                    <stream ref="fileItemReader" />
                </streams>    
                <skippable-exception-classes>
                    <include class="java.lang.Exception"/>
                    <exclude class="org.springframework.beans.factory.BeanCreationNotAllowedException"/>
                    <exclude class="java.lang.IllegalStateException"/>
                    <exclude class="javax.naming.NameNotFoundException"/>
                </skippable-exception-classes>            
            </chunk>                
             <listeners>
                <listener ref="loggerListener"/>     
            </listeners>    
        </tasklet>
    </step>
    <step id="step2">    
        <tasklet ref="mailTasklet"/>
    </step>        
</job>

Für die Nutzung von Platzhaltern muss nicht mehr der Umweg über einen StepExecutionResourceProxy genommen werden. Mit dem eingeführten late-binding von Job-Parametern wird das etwas eleganter gelöst. Die Ausdrücke sind in der Spring Expression Language formuliert, womit sich noch einige weitere nützliche Features ergeben. Die Angabe von scope=“step“ ist wichtig, damit der ApplicationContext den Step jedes Mal neu instanziiert, wenn der Job gestartet wird.

<bean id="itemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">    
    <property name="comments">
         <list>
            <value>#</value>
            <value>**</value>
        </list>        
    </property>    
    <property name="resource" value="#{jobParameters['file.name']}"/>        
    <property name="lineMapper" ref="flatFileLineMapper"/>                        
</bean>

Für die Transformation der Items wird nun der PatternMatchingCompositeLineTokenizer bzw. PatternMatchingCompositeLineMapper verwendet. Im Vergleich zum PrefixMatchingCompositeLineTokenizer kann man hier mit Patterns arbeiten und ist nicht nur auf das Präfix des Satzes beschränkt, was die Flexibilität deutlich verbessert. Ein weiterer Vorteil ist die Möglichkeit, dass man nun die Tokenizer beliebig den jeweiligen FieldSet-Mappern zuordnen kann, was die Testbarkeit und Kapselung optimiert, insbesondere bei komplexen Datenstrukturen.

<bean id="flatFileLineMapper"
    class="org.springframework.batch.item.file.mapping.PatternMatchingCompositeLineMapper">
    <property name="tokenizers">
        <map>
            <entry key="10*" value-ref="recordType10" />
            <entry key="20*" value-ref="recordType20" />
            <entry key="21*" value-ref="recordType21" />
        </map>
    </property>
    <property name="fieldSetMappers">
        <map>
            <entry key="1*" value-ref="fieldSetMapper1" />
            <entry key="2*" value-ref="fieldSetMapper2" />
        </map>
    </property>
</bean>

Fazit

Das gezeigte Beispiel ist nicht sehr komplex und kann nicht alle Neuerungen/Änderungen beinhalten. Darüber hinaus gibt es verschiedene Arten von Jobs. Es geht hier nicht immer um Dateiverarbeitung 😉 Aber generell lässt sich sagen, dass für die Umstellung ein gewisses Maß an Vorwissen vorhanden sein muss, um die kleinen Hürden erfolgreich zu überwinden. Diese Investition lohnt sich aber, da man mit der 2.1 nicht nur eine stabilere Version hat, sondern man sich auch nochmal Gedanken über die einzelnen Batches macht und vielleicht noch den einen oder anderen Bug oder vorhandene Fehlerquelle dabei ausbaut. Wichtig zu wissen ist allerdings, dass man Spring 3.x im Einsatz haben muss. Für große Infrastrukturen mit vielen Batches würde ich bei der Migration über die Entwicklung eines Skriptes nachdenken, was zumindest die Grundgerüste der XML-Konfigurationen transformiert. Ich als alter COBOL/Host-Entwickler bin wirklich begeistert von dem Framework und ich kann jedem nur ans Herz legen mal einen ausführlichen Blick darauf zu werfen 🙂

Dennis Schulte

Dennis Schulte ist seit 2009 als Senior IT Consultant bei der codecentric AG tätig. Er unterstützt seine Kunden insbesondere im Bereich Enterprise-Architekturen, Microservices, Continuous Delivery, DevOps und der Optimierung von IT-Prozessen. Aufgrund seiner langjährigen Erfahrung als Architekt und Entwickler verfügt er über ein umfassendes Wissen im Bereich Java und Open-Source-Technologien. Seine Projektschwerpunkte liegen in der Architekturberatung und der Durchführung von Projekten in Enterprise-Unternehmen.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.