Framework and FoundationsAvalon Framework is the central piece to the entire Avalon project. If you understand the contracts and constructs defined in the framework, you can understand anything that uses it. Remember the principles and patterns we have already discussed so far. In this section, we will expound on how the Role concept works practically, the lifecycle of Components, and how the interfaces work. Defining the Component's RoleIn Avalon, all Components have a role. The reason is that you retrieve your Components by role. At this stage, the only concern area we are using is the signature of the role. If you recall in the second section, we defined a Component as "the combination of a work interface and the implementation of the interface". That work interface is your role. Creating the Role's InterfaceBelow you will find an example interface, followed by some best practices along with their reasoning. package org.apache.bizserver.docs; public interface DocumentRepository { String ROLE = DocumentRepository.class.getName(); Document getDocument(Principal requestor, int refId); } Best Practices
Choosing the Role's NameIn Avalon, every Role has a name. It is how you get references to other Components in the system. The Avalon team has outlined some idioms to follow for the naming of your role. Naming Idioms
Overview of Framework InterfacesThe entire Avalon Framework can be divided into seven main categories (as is the API): Activity, Service, Configuration, Context, Logger, Parameters, Thread, and Miscellany. Each of those categories (except Miscellany) represents a unique concern area. It is common for a Component to implement several interfaces to identify all the concern areas that the Component is worried about. This will allow the Component's container to manage each Component in a consistent manner. Lifecycle for Avalon InterfacesWhen a framework implements several interfaces to separate the concerns of the Component, there is potential for confusion over the order of method calls. Avalon Framework realizes this, and so we developed the contract for lifecycle ordering of events. If your Component does not implement the associated Interface, then simply skip to the next event that will be called. Because there is a correct way to create and prepare Components, you can set up your Components as you receive events. The Lifecycle of a Component is split into three phases: Initialization, Active Service, and Destruction. Because these phases are sequential, we will discuss the events in order. In addition, the act of Construction and Finalization is implicit due to the Java language, so they will be skipped. The steps will list the method name, and the required interface. Within each phase, there will be a number of stages identified by method names. Those stages are executed if your Component extends the associated interface specified in parenthesis. InitializationThis list of stages occurs in this specific order, and occurs only once during the life of the Component.
Active ServiceThis list of stages occurs in this specific order, but may occur multiple times during the life of the Component. Please note that should you choose to not implement the Suspendable interface, it is up to your Component to ensure proper functionality while executing any of the Re* stages.
DestructionThis list of stages occurs in the order specified, and occurs only once during the life of the Component.
Avalon Framework ContractsIn this section, we will cover all the sections alphabetically with the exception of the most important concern area: Component.
ServiceThis is the core of Avalon Framework. Any interface defined in this concern area will throw ServiceException.
A Component that uses other Components needs to implement either this
interface or the old Composable interface. The new interface is the
preferred way of doing things. The interface has only one method
The contract surrounding this interface is that the
This interface along with any other interface that has methods
specified uses the Inversion of Control pattern. It is called by
the Component's container, and only the Components that this
Component needs should be present in the
Reserviceable?The Recomposable interface has no replacement in the Serviceable package. Use of Recomposable has been extremely rare, and many applications that use avalon do not provide support for it. ActivityThis group of interfaces refers to contracts for the life cycle of the Component. If there is an error during any method call with this group of interfaces, then you can throw a generic Exception. Disposable
The
The contract surrounding this interface is that the
Initializable
The
The contract surrounding this interface is that the
Startable
The
The contract surrounding this interface is that the
Suspendable
The
The contract surrounding this interface is that
Configuration
This group of interfaces describes the concern area of configuration.
If there are any problems, such as required
Configurable
Components that modify their exact behavior based on configurations
must implement this interface to obtain an instance of the
The contract surrounding this interface is that the
Configuration
The
There is a contract that says that if a
You will notice that you may not get parent
Reconfigurable
Components that implement this interface behave very similar to
Context
The concept of the
Context
The
There is no set contract with the
Contextualizable
A Component that wishes to receive the container's
The contract surrounding this interface is that the
Recontextualizable
Components that implement this interface behave very similar to
Resolvable
The Resolvable interface is used to mark objects that need to be
resolved in some particular context. An example might be an object
that is shared by multiple
LoggerEvery system needs the ability to log events. Avalon uses its LogKit project internally. While LogKit does have ways of accessing a Logger instance statically, the Framework wishes to use the Inversion of Control pattern. LogEnabled
Every Component that needs a Logger instance implements this
interface. The interface has one method named
The contract surrounding this method is that it is called only once during the Component's lifecycle before any other initialization step. Logger
The
Parameters
Avalon realizes that the Configuration object hierarchy can be
heavy in many circumstances. Therefore, we came up with a
Parameterizable
Any Component that wants to use
The contract is that this is called once during the lifecycle of
the Component. This interface is not compatible with the
Parameters
The
While there are similarities between the
<parameter name="param-name" value="param-value"/> ComponentThis used to be the core of Avalon Framework. The Component interface and it friends have been deprecated in favor of the Service package, which is exactly the same, except that the service package uses java.lang.Object in place of the Component interface. Any interface defined in this concern area will throw ComponentException. ComponentBefore the service package was put in place, every Avalon Component had to implement the Component interface. We have removed this restriction in the service package. The Component Manager and Component Selector only handle Components. There are no methods associated with this interface. It is only used as a marker interface. For maximum backward compatibility with existing applications, it can still be useful to implement the Component interface as older applications may depend on it being available.
Any Component must use default no parameter constructors. All
configurations are done with the
Composable
A Component that uses other Components needs to implement either this
interface or the new Serviceable interface. The new interface is the
preferred way of doing things. The interface has only one method
The contract surrounding this interface is that the
This interface along with any other interface that has methods
specified uses the Inversion of Control pattern. It is called by
the Component's container, and only the Components that this
Component needs should be present in the
Recomposable
On rare occasions, a Component will need a new
The contract surrounding the interface states that the
Thread
The thread marker interfaces are used to signal to the container
essential semantic information regarding the Component use. They
mark a component implementation in regards to thread safety. It is
a best practice to delay implementing these interfaces until the
final Component implementation class. This avoids complications
when an implementation is marked
Single Threaded
is that the interface or the implementation precludes this
Component being accessed by several threads simultaneously. Each
thread needs its own instance of the Component. Alternatively, you
may use Component pooling instead of creating a new instance for
every request for the Component. In order to use pooling, you will
need to implement Avalon Excalibur's
ThreadSafe
The contract with
MiscellanyThe classes and interfaces in the root package for Avalon Framework incorporates Cascading Exceptions, and a couple of generic utilities. However, one class deserves mention beyond the others. VersionJava versioning techniques are entries in the manifest file in a jar. The problem is, when the jar is unpacked you lose the versioning information, and the versioning is in an easily modified text file. When you couple this with a higher learning curve, detecting Component or Interface versions is difficult.
The Avalon team came up with the Version object to allow you to
have easily determined versions, and to compare versions. You may
implement the
|