The main purpose of the Application structure artifact is to keep everything in the same box, and allowing us to navigate the Structure. So, from a client code perspective, the Application is of no use, other than being part of bring Qi4j to life. Qi4j doesn't start automatically and can be run in most environments, by requiring that the bootstrapping of Qi4j is done by client code. We call this the Bootstrap Phase. The code in the custom bootstrapper will need to access additional Jars from the regular domain code, and we strongly recommend that you make this separation in your project as well.
At this point, where an ApplicationInstance exists, it is possible to initialize the application components with instances created in, data computed in or received from, the controlling bootstrap code.
Once the initialization phase is complete, the bootstrap controller will call the ApplicationInstance.activate() method to start things up.
Recap of sequence;
For really small applications, demos, testcases and so forth, it doesn't make sense to create a elaborate Application structure. For this purpose, there is a convenient short-cut to establish a single Layer, single Module application. The full code looks like this;
Behind the scenes of the SingletonAssembler a little bit more elaborate bootstrap sequence is happening. The code below shows what is the actual required sequence to start up Qi4j.
// initialize the Structure
:
// activate the application
application.activate()
The Assembler.assemble( ModuleAssembly assembly ) method is called when the Qi4j Runtime needs to populate the ModuleAssembly with its Composites, Objects, Services and other information.
Another standard setup is applications consisting of a small number of Layers that are directly on top of each other (with out bypassing, forking and converging Layers), you can supply a Assembler[][][], with Layer in the first index, Module in the second index and any number of Assembler instances in the last index. This will look like;
Finally, we can assemble the Application by manually building up the Modules and Layers. This allow for a totally free structure, as long as the rules for no cyclic reference of the Layers are kept.
public static void Main( String[] args )
{
instance = new Main();
instance.setUp();
// assuming some code has a non-daemon thread.
}
private void setUp()
{
Qi4jRuntime is = new Energy4Java();
runtime = is;
ApplicationAssemblyFactory assemblyFactory =
new ApplicationAssemblyFactory();
ApplicationFactory factory =
new ApplicationFactory( runtime, assemblyFactory );
ApplicationAssembly app = createAssembly( assemblyFactory );
ApplicationContext context = factory.newApplication( assembly );
String applicationName = "Example Application";
ApplicationInstance instance =
context.newApplicationInstance( applicationName );
}
private ApplicationAssembly createAssembly(
ApplicationAssemblyFactory factory )
{
ApplicationAssembly app = factory.newApplicationAssembly();
LayerAssembly webLayer = createWebLayer( app );
LayerAssembly domainLayer = createDomainLayer( app );
LayerAssembly infraLayer = createInfrastructureLayer( app );
webLayer.uses( domainLayer );
webLayer.uses( infraLayer ); // Accesses the WebService
domainLayer.uses( infraLayer ); // For persistence
return app;
}
private LayerAssembly createWebLayer(
ApplicationAssembly application )
{
LayerAssembly layer = application.newLayerAssembly();
createCustomerWebModule( layer );
return layer;
}
private LayerAssembly createDomainLayer(
ApplicationAssembly application )
{
LayerAssembly layer = application.newLayerAssembly();
createCustomerDomainModule( layer );
// :
// :
return layer;
}
private LayerAssembly createInfrastructureLayer(
ApplicationAssembly application )
{
LayerAssembly layer = application.newLayerAssembly();
createWebServiceModule( layer );
createPersistenceModule( layer );
return layer;
}
private void createCustomerWebModule( LayerAssembly layer )
{
ModuleAssembly assembly = layer.newModuleAssembly();
assembly.addComposites( CustomerViewComposite.class );
assembly.addComposites( CustomerEditComposite.class );
assembly.addComposites( CustomerListViewComposite.class );
assembly.addComposites( CustomerSearchComposite.class );
}
private void createCustomerDomainModule( LayerAssembly layer )
{
ModuleAssembly assembly = layer.newModuleAssembly();
assembly.addEntities( CustomerEntity.class );
assembly.addEntities( CountryEntity.class );
assembly.addComposites( AddressComposite.class );
}
private void createWebServiceModule( LayerAssembly layer )
{
ModuleAssembly assembly = layer.newModuleAssembly();
// Someone has created an assembler for a Jetty Web Service.
JettyAssembler jetty = new JettyAssembler( 8080 );
assembly.addAssembler( neo );
}
private void createPersistenceModule( LayerAssembly layer )
{
ModuleAssembly assembly = layer.newModuleAssembly();
// Someone has created an assembler for the Neo EntityStore
NeoAssembler neo = new NeoAssembler( "./neostore" );
assembly.addAssembler( neo );
}
}