Purpose
The purpose of this proposal is to describe the need for a Component Oriented Programming framework, particularly Avalon.
Introduction to Component Oriented Programming (COP) and Avalon.
Avalon uses the Inversion of Control(IoC) and Seperation of Concerns (Soc) Design patterns. Check out the Framework Glossary for a definition of terms.
- (IoC) The design pattern which states that a component NEVER controls its own lifecycle methods and that all dependencies are provided by a hosting object (a container or some caller object). Control of a component is completely given to the calling object.
- (SoC) is a very important design pattern which is central to IoC development.
In fact, without first applying proper SoC principles, it can be very difficult to take advantage of IoC. Separation of Concerns means a problem should be seperated into a set of components each of which focus on only one core concern. Imagine, for example, a large corporation made of many divisions such as human resources, accounting, logistics, sales, market, manufacturing, etc. Each of these divisions handles only one aspect, or concern, of the overall business. The human resources team does not investigate product defects and the marketing team does administer the corporate intranet. Likewise, a software application will generally have many concerns – logging, caching, security, business logic, persistance, etc. Separating out these concerns into seperate software modules allows each module concern itself with only doing one job well.
For more information on IoC go to IoC
Each component in an application plays a role which is defined by the service it offers. Components come in all shapes and sizes – most everything can be defined as a component at one layer or another. For example, the persistence component may be comprised of datasources, caching, and transaction components.
A system may have several different implementations of a particular service which is needed for different contexts within the over all application. The roleManager keeps track of these relationships.
Since components are only tied to one another via their roles, you are free to change, upgrade, swap, migrate, or in general transform your component implementation without incurring application instability. As long as the new implementation can fulfill the contract defined by the component role, you can replace existing implementations with newer ones. For example, one could easily write adaptors for third-party modules, be they commercial or open source, to be used as components in your Avalon-based project.
Every object has a lifecycle, for example a JavaBean. Instantiated usually via its constructor and some fields are set (or unset) via getters and setters. Methods are then called and re-called before the object is finally discarded for the garbage collector to take care of.
A container is a special component which handles the lifecycles of the components it hosts. Only the container has this responsibility of lifecycle management. a ServiceManager is used by the container to properly handle component lifecycle methods. Between the ServiceManager and the RoleManager, the container can find roles and bring them to life.
Components only interact via well defined contracts and calling (or parent) components are responsible for the handling of referenced (or child) components. Following this design increases the stability of your code since each component behaves in well defined ways and lifecycle management is strictly controlled.
Some of the key features of Avalon
- Model Integration - The Avalon Meta Model defines the functional structure of component types and services. A Type definition contains information about deployment and runtime dependencies together with information about the services that a component type can provide. Example of Type Definition
- Javadoc - Reference specification of the Javadoc Tags used to support automation of component and service meta info generation. Example of Javadoc tags
- Avalon Composition - Avalon Composition ties together component and underlying component type model, component and container deployment directives, and the runtime environment. Example of Composition
- Context Management - The composition model API provides support for dynamic management of the containment model - enabling full model-driven control. Example of Context Management
- Configuration Management - The multi-tired configuration model covering static type based defaults, packaged configuration profiles, explicit deployment configurations, and overridding configurations. Example of Configuration Management
- Classloader Management - Leveraging the Avalon Repository resource management facilities, the composition package provides support for logical artifacts that are independent of a particular physical url, including systejlm and application cache management. Example of Classloader & Repository
Merlin
Merlin is the reference implementation of Avalon. Avalon Merlin system diagram:

- A Block defines a component or a set of components. This could also be seen as a service if one choses to make a component or set of components a service. A component does not have to be defined as a service.
- Merlin provides support for packaging configurations. By default a block and a component is configured using the default configuration. This configuration can be overridden.
Sail and Avalon
How does Avalon fit into SAIL? The SAIL Framework is going to need various services for clients to use. Some of the Services that will be needed are; User Services, Sercuity Services, Logging Services, VLE Services(creation of Notes, hints, etc...), Transaction Services, Messaging Services, etc..
You can make any component and call it a service in any system. The difference with Avalon is that it provides the mechanisms for lookup, life cycle management and the ability to turn any POJO into a service.
For instance, someone created a random number generator service and we want to use it. The container will create and dispose of this component when it needs to or if it is a singleton grab the one that currently is instantated.
public class HelloComponent extends AbstractLogEnabled implements Initializable, Serviceable, Disposable { RandomGenerator m_random = null; /** * Servicing of the component by the container during * which service dependencies declared under the component * can be resolved using the supplied service manager. * * @param manager the service manager * @avalon.dependency type="tutorial.RandomGenerator:1.0" * key="random" * @avalon.dependency type="tutorial.Identifiable" */ public void service( ServiceManager manager ) throws ServiceException { m_random = (RandomGenerator) manager.lookup( "random" ); ...... }