A component lives within something called a container. The contract between a container and a contained component is simple: the container is required to take a component through what is called its lifecycle.
The Avalon project provides an application that functions as a container for componentized applications called Merlin.
The lifecyle methods from the Avalon Framework sub-project are designed to be used by just about any component hosted by any container. Of course, the API in question may well require additional interfaces for strongly typed functionality, but these interfaces should negate the need for any duplication of effort.
The lifecycle of a component specifies the methods that can be called on it,
and the order in which this may happen. Some methods can be called only once
in a specific phase
of a component's lifecycle, others may
be called multiple times. These methods are called the lifecycle methods.
It is up to each container to indicate which lifecycle methods it will honor. This should be clearly documented together with the description of the container. A sister project to Phoenix supports all of the lifecycle methods defined in the Avalon Framework API.
A component exposes its lifecycle methods by implementing the lifecycle interfaces. Each of these defines one or more methods that represent a specific phase in a component's lifecycle. The defined interfaces are:
Note:java.lang.Runnable has also been in use as a lifecycle interface. This is not recommended and is not supported by Avalon. Instead, the run() method is the responsibility of the component itself. If you wish to use it, call it from within start() or another method.
The order in which the various lifecycle methods are called is very specific. While none are required (it is possible to have a component implementing none of the lifecycle methods, although the use of that would be limited), some can only be used when others are as well. This is best explained using a few examples.
The lifecycle of a component implementing only Configurable for example will be:
The lifecycle of a component implementing only Serviceable will be:
If a component implements more than one interface the order of the events (service, configure etc.) follow a specific order. A component implementing all above interfaces (including Runnable) will follow these specific paths.
Startup Phase:
At various or repeated times after startup:
Shutdown Phase:
These lifecycle methods are only called once in the entire life of a component:
These lifecycle methods are called at least once and possibly more, depending on the container:
The methods suspend() and resume() are not guaranteed to be called at all, even when implemented. They can be called more than once, but only after one another and between start() and stop(). The reason they exist is so the container can notify the component it needs to temporarily stop any operations. The container may need to perform some synchronized operation on one of the components used by this component, or it may wish to call any of the following methods, which can also be called zero or more times, and only between a suspend() and a resume().