Podpora zpracování konfigurace modulu

Podpora zpracování konfigurace modulu

Zkopírovat odkaz na sekciMožnosti

Pro účely zjednodušení načítání XML konfigurace je dostupná třída ConfigHelper. Ta obsahuje užitečné metody, které vám umožní:

Zkopírovat odkaz na sekcivytvářet instance a class objekty z řetězce

získávat class objekty ze stringu a tyto classy bezpečně instanciovat (s obalením chyby do případné CpsException s návodným hlášením problému)

metody getClassByPath, getClassInPackageByElementName, getImplementationClassInPackage, instantiateClass

Zkopírovat odkaz na sekcinapopulovat data ze sitemapy přes POJO settery do existujících instancí

do existující instance nastaví property dle XML atributů nebo poduzlů

metody configureAccordingToAttributes, configureAccordingToSubElements, configure

Zkopírovat odkaz na sekciinicializovat objekty Springovým způsobem

umožní zpracovat lifecycle callbacky jako InitializingBean, *Aware interfacy atd., autowiring by name z dodaného aplikačního kontextu

metody addUsedObject, initUsedObjects, isObjectRegisteredInUsedObjects

Zkopírovat odkaz na sekcikombinovaně vytvářet instanci dle konfigurace a naplnit ji hodnotami

kombinované metody, které zároveň instanciují i konfigurují třídu podle sitemapy

metody getInstantiatedAndConfiguredClass, getInstantiatedAndConfiguredClassInPackage, getInstantiatedInstanceFromIndex, getInstantiatedAndConfiguredInstanceFromIndex

„indexové” metody nečtou informace o kompletních názvech tříd ze sitemap, ale hledají je podle klíčového slova v mapě - jeden index obsahuje jen třídy objektů Map, druhý index již hotové instance Map, v případě instancí se nevytváří kopie, ale použije se již hotový objekt, který se dále z dat sitemapy již nekonfiguruje

Zkopírovat odkaz na sekcizískat data z XML v jednoduché formě k dalšímu zpracování

převede konfigurační tagy do základních datových struktur

metody getChildrenAsMap, recursivelyAddSubElements

Zkopírovat odkaz na sekciVazba na lifecycle

Typicky probíhá načítání konfigurace ze sitemapy ještě před inicializací aplikačního kontextu - tj. instance objektů vznikají před tím, než máme k dispozici funkční aplikační kontext, ze kterého bychom mohli autowirovat dependence, načítat Resourcy atp.

Z toho důvodu je ConfigHelper navrhnut dvoufázově

  • v první fázi vám pomůže vytvořit instance objektů a napopulovat je daty ze sitemapy
  • a v druhé fázi, kdy už máte k dispozici funkční aplikační kontext zavoláte metodu initUsedObjects která provede Springovou inicializaci všech objektů
    • objekty se nestanou součástí aplikačního kontextu (jsou bezejmenné)
    • jen se provede jejich inicializace jako by v něm byly + autowiring byName.

Zkopírovat odkaz na sekciRegistrace objektů

Pokud vytváříte instance prostřednictvím metod ConfigHelperu (např. instantiateClass), nemusíte se o registraci instance starat - je do sady „usedObjects” zařazena automaticky. Pokud si vytváříte instance objektů bokem, je nutné je do seznamu zařadit explicitně voláním metody addUsedObject(s).

Zkopírovat odkaz na sekciResource populace

Jak již bylo uvedeno populace dat se děje ve chvíli, kdy ještě nemáme k dispozici funkční kontext. Nicméně objekty typu Resource vznikají pomocí tzv. ResourceLoaderu, kterým je právě zmíněný aplikační kontext - tj. vzniká nám tu cyklická dependence pro inicializaci.

Z toho důvodu vznikla třída zvaná DelegatingResource a odpovídající DelegatingResourceEditor, které umí zastupovat libovolný cílový Resource objekt.

Tj. vytvořené instance budou mít do fieldů typu Resource injektován objekt typu DelegatingResource, jehož inicializace finální inicializace se provede až ve chvíli, kdy je aplikační kontext k dispozici. Inicializace všech DelegatingResourců se děje ve chvíli volání metody initUsedObjects.

Zkopírovat odkaz na sekciPříklady

java
1 public class JobMgrXmlConfigParser {2    3    public JobMgrConfig parse(CpsModuleConfigSupport configSupport) {4        final JobMgrConfig jobMgrConfig = new JobMgrConfig();5        // prevede xml <asyncDisabled>false</asyncDisabled> do volani setAsyncDisabled(false)6        configHelper.configureAccordingToSubElements(7            getConfigRootElement(configSupport),8            jobMgrConfig,9            new String[] {"checks", "jobsConfigOverride"}10        );11        return jobMgrConfig;12    }13}

Složitější parser

java
1 public class XmlWorkflowConfigParser implements WorkflowConfigParser {2    3    public WorkflowDefinition configureWorkflow(ConfigElement workflowElement) {4        // naplni XML atributy do pojo field5        WorkflowDefinition workflowDefinition = new WorkflowDefinition(workflowElement.getAttributeValue("id"));6        configHelper.configureAccordingToAttributes(workflowElement,workflowDefinition,new String[]{"id","class"});7        // dataloader plne dle XML konfigurace vcetne volby cilove tridy8        ConfigElement dataLoaderElement = workflowElement.getChildElement("dataLoader");9        if (dataLoaderElement!=null) {10            // instance z <dataLoader class="com.fg.edee.workflow.integration.business.EdeePageWorkflowExternalDataLoader"/>11            WorkflowExternalDataLoader dataLoader = 12                (WorkflowExternalDataLoader) configHelper.getInstantiatedAndConfiguredClassInPackage(dataLoaderElement, null, true, true);           13            workflowDefinition.setDataLoader(dataLoader);14        }15        // metadata - zpracovani dle fixni package, kde nazev tagu odpovida nazvu tridy16        List<ConfigElement> metadataList = workflowElement.getChildElements();17        for (ConfigElement metadataElement : metadataList) {18            final String metadataName = metadataElement.getElementName();19            // chceme pouze tagy dle konvence20            if (metadataName.endsWith("Metadata")) {21                // instance z konfigurace <pageMetadata pageSystemId="TARGET_PAGE" pageLang="cs"/>22                final Class metadataClass = configHelper.getImplementationClassInPackage(metadataElement,23                        "com.fg.edee.workflow.core.metadata");24                final Object metadata = configHelper.instantiateClass(metadataClass, null);25                configHelper.configureAccordingToAttributes(metadataElement, metadata, new String[]{"class"});26                configHelper.configureAccordingToSubElements(metadataElement, metadata);27                Assert.isInstanceOf(WorkflowMetadata.class,metadata);28                workflowDefinition.setMetadata(metadata);29            }30        }31        return workflowDefinition;32    }33}