The definition and composition of the
components that form an application is done in the Application
Description file. This is an xml file which defines all components
and their interconnections.
Typically a user of the framework will define an Application
Description file, implement the components and will then
instantiate and interact with the component composition through
the API that the framework provides.
A simple example of an Application Description below:
The application description defines 2 components, compA, which is
implemented by the ComponentA class and compB which is implemented
by the ComponentB class. compA has a receptacle pointing at an
interface provided by compB and also provides another interface
that is not used by any other component, but can be used by a user
of the framework.
The following code instantiates the application
and the following code shows how to obtain a reference and use
an interface provided by the components within the application.
Component
Implementation
So far we have seen hoe
to define a simple application description and how to
instantiate the framework, but not how to implement components.
The component implementation class must implement (at least) all
formal interfaces that the component offers.
Below is the implementation of compB and its interface.
aThe component implementation follows a POJO approach
with annotations. The @InitMethod (one of the annotations of the
framework) instructs the JLCF framework to call this method after
instantiating the object.
The implementation of compA, is more interesting as the component
defines a Receptacle and a Property.
The constructor
must define which fields are of type Property and a Receptacle and
their respective names. The constructor must not contain other
arguments besides Receptacles and Properties as the framework will
not be able to instantiate an instance of the component.
The output of the example:
is the following:
[main] INFO org.jlcf.core.JLCFContainer - JLCF container
instance initialized
[AbstractQueueProcessorThread :JLCFContainerProcessor] INFO
org.jlcf.core.util.AbstractQueueProcessorThread -
org.jlcf.core.util.AbstractQueueProcessorThread thread started.
[AbstractQueueProcessorThread :JLCFContainerProcessor] INFO
org.jlcf.core.JLCFFrameworkUtilities - component:compA
instantiated
[AbstractQueueProcessorThread :JLCFContainerProcessor] INFO
org.jlcf.core.JLCFFrameworkUtilities - component:compB
instantiated
[AbstractQueueProcessorThread :JLCFContainerProcessor] INFO
org.jlcf.core.JLCFContainerProcessor - connecting compA / compoB
-> compB/compbintf
[AbstractQueueProcessorThread :JLCFContainerProcessor] INFO
ComponentA - component ComponentA version:1.01 initialized
[AbstractQueueProcessorThread :JLCFContainerProcessor] INFO
ComponentB - Init method called
[main] INFO ComponentA - doTask called. Calling component B with
input=HellO
[main] INFO ComponentB - method called, with input :HellO
[main] INFO ComponentA - received reply from component B :HELLO
[main] INFO ComponentA - doTask called. Calling component B with
input=HellO
[main] INFO ComponentB - method called, with input :HellO
[main] INFO ComponentA - received reply from component B :HELLO
[main] INFO ComponentA - doTask called. Calling component B with
input=HellO
[main] INFO ComponentB - method called, with input :HellO
[main] INFO ComponentA - received reply from component B :HELLO
[main] INFO ComponentA - doTask called. Calling component B with
input=HellO
[main] INFO ComponentB - method called, with input :HellO
[main] INFO ComponentA - received reply from component B :HELLO
The framework also supports powerful concepts such as
interceptors, callbacks and the ability to dynamically replace a
component implementation at runtime. See the examples of the JLCF
distribution and the documentation for more details.