Programování

Použijte Spring k vytvoření jednoduchého modulu pracovního postupu

Mnoho podnikových aplikací Jave vyžaduje, aby bylo zpracování prováděno v kontextu odděleném od kontextu hlavního systému. V mnoha případech tyto back-endové procesy provádějí několik úkolů, přičemž některé úkoly závisí na stavu předchozí úlohy. S požadavkem na vzájemně závislé úlohy zpracování se implementace pomocí jediné procedurální sady volání metod obvykle ukáže jako nedostatečná. Díky využití Spring může vývojář snadno oddělit proces back-endu do agregace aktivit. Kontejner Spring spojuje tyto aktivity a tvoří jednoduchý pracovní postup.

Pro účely tohoto článku jednoduchý pracovní postup je definována jako libovolná sada činností prováděných v předem stanoveném pořadí bez interakce uživatele. Tento přístup se však nenavrhuje jako náhrada za existující rámce pracovního postupu. Pro scénáře, kde jsou nutné pokročilejší interakce, jako je rozdvojení, připojení nebo přechody na základě vstupu uživatele, je lépe vybaven samostatný otevřený zdrojový nebo komerční modul pracovního postupu. Jeden projekt s otevřeným zdrojovým kódem úspěšně integroval složitější návrh pracovního toku do Spring.

Pokud jsou úkoly pracovního postupu zjednodušující, má přístup jednoduchého pracovního postupu smysl na rozdíl od plně funkčního samostatného rámce pracovního toku, zejména pokud je Spring již používán, protože je zaručena rychlá implementace bez vzniku doby rozběhu. Kromě toho, vzhledem k povaze lehkého Springova kontejneru inverze kontroly, Spring snižuje režii prostředků.

Tento článek stručně představuje pracovní postup jako téma programování. Pomocí konceptů pracovního toku je Spring použit jako rámec pro řízení motoru pracovního toku. Poté jsou diskutovány možnosti produkčního nasazení. Začněme s myšlenkou jednoduchého pracovního postupu zaměřením na návrhové vzory pracovního postupu a související informace na pozadí.

Jednoduchý pracovní postup

Pracovní postup modelování je téma, které bylo studováno již v 70. letech minulého století a mnoho vývojářů se pokusilo vytvořit standardizovanou specifikaci modelování pracovního postupu. Vzory pracovního postupu, bílá kniha W.H.M. van der Aalst a kol. (Červenec 2003), se podařilo klasifikovat sadu návrhových vzorů, které přesně modelují nejběžnější scénáře pracovního postupu. Mezi nejtriviálnější vzory pracovních toků patří vzor Sequence. Podle kritérií jednoduchého pracovního postupu se vzor pracovního postupu Sequence skládá ze sady aktivit prováděných v pořadí.

Diagramy aktivit UML (Unified Modeling Language) se běžně používají jako mechanismus pro modelování pracovního toku. Obrázek 1 ukazuje základní proces pracovního postupu Sekvence modelovaný pomocí standardního diagramu aktivity UML.

Pracovní postup Sekvence je standardní vzor pracovního postupu převládající v aplikacích J2EE. Aplikace J2EE obvykle vyžaduje posloupnost událostí, které se vyskytnou v podprocesu na pozadí nebo asynchronně. Schéma aktivity na obrázku 2 ilustruje jednoduchý pracovní postup pro informování cestujících, kteří mají zájem, že se snížila cena letenky do jejich oblíbeného cíle.

Pracovní postup leteckých společností na obrázku 1 je zodpovědný za vytváření a odesílání dynamických e-mailových oznámení. Každý krok v procesu představuje aktivitu. Než se pracovní tok uvede do pohybu, musí dojít k nějaké externí události. V tomto případě je touto událostí pokles rychlosti pro letovou trasu letecké společnosti.

Pojďme se projít obchodní logikou pracovního postupu letecké společnosti. Pokud první aktivita nenajde žádné uživatele zajímající se o oznámení o poklesu rychlosti, celý pracovní postup se zruší. Pokud jsou uživatelé se zájmem objeveni, zbývající aktivity jsou dokončeny. Následně transformace XSL (Extensible Stylesheet Language) vygeneruje obsah zprávy, po které se zaznamenají informace o auditu. Nakonec dojde k pokusu o odeslání zprávy přes server SMTP. Pokud se odeslání dokončí bez chyby, zaznamená se úspěch a proces se ukončí. Pokud se ale při komunikaci se serverem SMTP vyskytne chyba, převezme ji speciální rutina zpracování chyb. Tento kód pro zpracování chyb se pokusí zprávu znovu odeslat.

Vzhledem k příkladu letecké společnosti je zřejmá jedna otázka: Jak byste mohli efektivně rozdělit postupný proces na jednotlivé aktivity? Tento problém je řešen výmluvně pomocí Spring. Pojďme rychle diskutovat o Spring jako inverzi Control rámce.

Obrácení kontroly

Jaro nám umožňuje odstranit odpovědnost za ovládání závislostí objektu přesunutím této odpovědnosti do kontejneru Spring. Tento přenos odpovědnosti se nazývá Inversion of Control (IoC) nebo Dependency Injection. Viz Martin Fowler „Inverze kontrolních kontejnerů a vzor injekce závislosti“ (martinfowler.com, leden 2004), kde najdete podrobnější diskusi o IoC a injekcích závislostí. Díky správě závislostí mezi objekty Spring eliminuje potřebu kód lepidla, kód napsaný pouze za účelem vzájemné spolupráce tříd.

Součásti pracovního postupu jako jarní fazole

Než se dostaneme příliš daleko, teď je ten správný čas projít si hlavní koncepty jara. The ApplicationContext rozhraní, dědí z BeanFactory rozhraní, ukládá se jako skutečná řídící entita nebo kontejner v rámci Spring. The ApplicationContext je zodpovědný za vytváření instancí, konfiguraci a správu životního cyklu sady fazolí známých jako Jarní fazole. The ApplicationContext je konfigurován uživatelem elektroinstalace Jarní fazole v konfiguračním souboru založeném na XML. Tento konfigurační soubor určuje povahu, ve které Spring fazole vzájemně spolupracují. Tak, na jaře mluvit, jarní fazole, které interagují s ostatními, jsou známé jako spolupracovníci. Ve výchozím nastavení existují jarní fazole jako singletony v ApplicationContext, ale atribut singleton lze nastavit na hodnotu false, což je efektivně změní tak, aby se chovaly v tom, co Spring volá prototyp režimu.

Zpět k našemu příkladu, při snížení ceny letenky, je jako poslední aktivita v příkladu procesu pracovního postupu připojena abstrakce rutiny odesílání SMTP (ukázkový kód k dispozici ve zdrojích). Jako pátá aktivita je tato fazole pojmenována příhodně aktivita5. Chcete-li odeslat zprávu, aktivita5 vyžaduje spolupracovníka delegáta a obslužnou rutinu chyb:

Implementace komponent pracovního toku jako Spring Beans má za následek dva žádoucí vedlejší produkty, snadné testování jednotek a velkou míru opětovného použití. Efektivní testování jednotky je evidentní vzhledem k povaze kontejnerů IoC. Pomocí kontejneru IoC, jako je Spring, lze během testování snadno vyměnit závislosti spolupracovníků s falešnými náhradami. V příkladu letecké společnosti an Aktivita Jarní fazole jako např aktivita5 lze snadno získat ze samostatného testu ApplicationContext. Nahrazení falešného delegáta SMTP aktivita5 umožňuje jednotkové testování aktivita5 odděleně.

Druhý vedlejší produkt, opětovné použití, je realizován aktivitami pracovního postupu, jako je transformace XSL. Transformace XSL, abstraktní do aktivity pracovního postupu, lze nyní znovu použít v jakémkoli pracovním postupu, který se zabývá transformacemi XSL.

Zapojení pracovního postupu

V poskytnutém rozhraní API (ke stažení ze zdrojů) ovládá Spring malou sadu hráčů, kteří komunikují způsobem, který představuje pracovní postup. Klíčová rozhraní jsou:

  • Aktivita: Zapouzdřuje obchodní logiku jednoho kroku v procesu pracovního postupu.
  • ProcessContext: Objekty typu ProcessContext jsou předávány mezi aktivitami v pracovním toku. Objekty implementující toto rozhraní jsou zodpovědné za udržování stavu při přechodu pracovního postupu z jedné aktivity na další.
  • ErrorHandler: Poskytuje metodu zpětného volání pro zpracování chyb.
  • Procesor: Popisuje fazole sloužící jako spouštěč hlavního vlákna pracovního toku.

Následující výňatek z ukázkového kódu je konfigurace Spring bean, která váže příklad letecké společnosti jako jednoduchý proces pracovního postupu.

             / property> org.iocworkflow.test.sequence.ratedrop.RateDropContext 

The Procesor sekvence třída je konkrétní podtřída, která modeluje vzor sekvence. K procesoru je připojeno pět aktivit, které procesor pracovního postupu provede v uvedeném pořadí.

Ve srovnání s většinou procedurálních backendových procesů řešení pracovního postupu opravdu vyniká jako schopnost vysoce robustního zpracování chyb. Obslužná rutina chyb může být pro každou aktivitu zvlášť připojena. Tento typ obslužné rutiny poskytuje jemnozrnné zpracování chyb na úrovni jednotlivých aktivit. Pokud není pro aktivitu připojen žádný obslužný program chyb, problém vyřeší obslužný program chyb definovaný pro celkový procesor pracovního postupu. V tomto příkladu, pokud dojde k neošetřené chybě kdykoli během procesu pracovního postupu, rozšíří se, aby ji zpracoval ErrorHandler fazole, která je zapojena pomocí defaultErrorHandler vlastnictví.

Složitější rámce pracovního postupu přetrvávají stav do úložiště dat mezi přechody. V tomto článku nás zajímají pouze jednoduché případy pracovního postupu, kdy je přechod stavu automatický. Informace o stavu jsou k dispozici pouze v ProcessContext během běhu skutečného pracovního postupu. Mít pouze dvě metody, můžete vidět ProcessContext rozhraní je na dietě:

veřejné rozhraní ProcessContext rozšiřuje Serializable {public boolean stopProcess (); public void setSeedData (Object seedObject); }

Beton ProcessContext třída použitá pro příklad pracovního postupu letecké společnosti je RateDropContext třída. The RateDropContext třída zapouzdřuje data nezbytná k provedení pracovního postupu poklesu rychlosti letecké dopravy.

Až dosud byly všechny instance fazole podle výchozího nastavení singletony ApplicationContextchování. Musíme ale vytvořit novou instanci RateDropContext třídy pro každé vyvolání pracovního toku letecké společnosti. Pro splnění tohoto požadavku Procesor sekvence je nakonfigurován, přičemž plně kvalifikovaný název třídy je processContextClass vlastnictví. Pro každé spuštění pracovního postupu je Procesor sekvence načte novou instanci ProcessContext od jara pomocí zadaného názvu třídy. Aby to fungovalo, nesmyslná jarní fazole nebo prototyp typu org.iocworkflow.test.sequence.simple.SimpleContext musí existovat v ApplicationContext (vidět rateDrop.xml pro celý seznam).

Nasazení pracovního postupu

Nyní, když víme, jak sestavit jednoduchý pracovní postup pomocí Springu, zaměřme se na vytváření instancí pomocí dat seedu. Abychom pochopili, jak nasadit pracovní postup, pojďme se podívat na metody vystavené ve skutečnosti Procesor rozhraní:

veřejné rozhraní Processor {public boolean podporuje (aktivita aktivita); public void doActivities (); public void doActivities (Object seedData); public void setActivities (aktivity seznamu); public void setDefaultErrorHandler (ErrorHandler defaultErrorHandler); }

Ve většině případů procesy pracovního postupu vyžadují počáteční podněty. K nastartování procesoru existují dvě možnosti: doActivities (Object seedData) metoda nebo její alternativa bez argumentů. Následující seznam kódů je doAcvtivities () implementace pro Procesor sekvence součástí ukázkového kódu:

 public void doActivities (Object seedData) {if (logger.isDebugEnabled ()) logger.debug (getBeanName () + "běží procesor .."); // načítání vložené aktivitami Spring List = getActivities (); // načtení nové instance Workflow ProcessContext ProcessContext context = createContext (); if (seedData! = null) context.setSeedData (seedData); for (Iterator it = activities.iterator (); it.hasNext ();) {Activity activity = (Activity) it.next (); if (logger.isDebugEnabled ()) logger.debug ("běžící aktivita:" + activity.getBeanName () + "pomocí argumentů:" + kontext); zkuste {context = activity.execute (kontext); } catch (Throwable th) {ErrorHandler errorHandler = activity.getErrorHandler (); if (errorHandler == null) {logger.info ("žádná obslužná rutina chyb pro tuto akci, spustit výchozí chybu" + "obslužná rutina a přerušit zpracování"); getDefaultErrorHandler (). handleError (kontext, th); přestávka; } else {logger.info ("spustit obslužnou rutinu chyb a pokračovat"); errorHandler.handleError (kontext, th); }}