Introduction

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 Phoenix . This is not exclusive, components adhering to lifecycle interfaces, can be mounted in custom containers. Cocoon and others mounts their own containers for components and invoke relevant methods from the lifecycle interfaces. See Containers .

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

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.

The Lifecycle Interfaces

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:

  1. LogEnabled
  2. Contextualizable
  3. Serviceable (replacement for Composable)
  4. Configurable
  5. Parameterizable
  6. Initializable
  7. Startable
  8. Suspendable
  9. Recontextualizable
  10. Recomposable
  11. Reconfigurable
  12. Reparameterizable
  13. Stoppable
  14. Disposable

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.

Phase Order

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.

Simple Examples

The lifecycle of a component implementing only Configurable for example will be:

  1. constructor
  2. configure
  3. finalize

The lifecycle of a component implementing only Serviceable will be:

  1. constructor
  2. service
  3. finalize

Complete

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:

  1. constructor as a consequence of instantiation
  2. contextualize
  3. service or compose
  4. configure
  5. parameterize
  6. initialize
  7. start

At various or repeated times after startup:

  1. suspend
  2. recontextualize
  3. recompose
  4. reconfigure
  5. reparameterize
  6. resume

Shutdown Phase:

  1. stop
  2. dispose
  3. finalize at some indeterminate moment by the garbage collector

Phases executed once

These lifecycle methods are only called once in the entire life of a component:

  • contextualize
  • service
  • configure
  • parameterize
  • initialize
  • dispose

Phases executed once or more

These lifecycle methods are called at least once and possibly more, depending on the container:

  • start
  • stop

The Suspendable Interface

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().

  • recontextualize()
  • recompose()
  • reconfigure()
  • reparameterize()