spring-projects/spring-xd — pull request #1215 by dturanski (2014-10-06 16:50:48+00:00)
Title: Module refactoring epic

Covers XD-2196 and XD-2197 since they are dependent.

* ContainerRegistrar refactoring extracts DeploymentListener to a top-level class along with all deployment logic and moves module creation logic to ModuleDeployer. Module creation is ultimately delegated to ModuleFactor. A module must be created before it is deployed, so DeploymentListener could easily invoke MF directly. Since DL uses ModuleDeployer extensively but only one method invocation to create a module instance, it seems cleaner to decouple DeploymentListener from ModuleFactory.

* ModuleFactory commits have some broader design impacts. I experimented with some different options before settling on the current approach which makes SimpleModule abstract. Currently there is a single subclass, ResourceConfiguredModule which implements all existing modules. This satisfies the following criteria:

** It should be possible to create a SimpleModule without going through the ModuleFactory. Formerly, SimpleModule loaded the XML resource in it's constructor. This is what needs to be decoupled. Requiring ModuleFactory and scoping SimpleModule's constructor to the same package creates some unnecessary impedance since MF requires a ModuleOptionsMetadataResolver (which is already overly complex IMHO). So creating a MF outside of the XD application context is problematic in situations like StreamPluginTests and JobPluginTests.

** A SimpleModule instance created via a simple constructor should work as expected. This means that loading the bean sources for the module must happen in the constructor. In one iteration I passed a strategy interface as an argument to the constructor to configure the module, but this is a real kludge IMO compared to using inheritance. A module should know how to create itself.

**ModuleFactory inspects the configuration provided in the ModuleDefinition and selects a module type based on available resources. The ResourceConfiguredModule currently duplicates some resource validation in also in the ModuleFactory. The separation of concerns is clearer when we consider, for example, how the JavaConfiguredModule would be implemented. The ModuleFactory could detect the presence of "base-package" in the module's properties file and select the JavaConfiguredModule based on that. The JavaConfiguredModule would be responsible for component scanning that package and configuring the AC accordingly.