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
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
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}