link
Avalon
Avalon Central
Home PlanetProductsCentral
Using Merlin
Managing Dependencies

A component type can declare dependencies on services provided by other components. Merlin will ensure that dependencies are resolved prior to creation of the dependent component. Dependencies are declared in the component xinfo resource and supplied by Merlin to the component using the Avalon Serviceable interface.

Resources supporting this tutorial are contained in the turorials/dependencies/auto package.

Adding a Serviceable method implementation

The following code fragment is the implementation of the Serviceable interface under the HelloComponent.java source.

Note the use of the @avalon.dependency tag.

HelloComponent.java

package tutorial;

import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;

/**
 * The HelloComponent is dependent on a RandomGenerator service.
 * @avalon.component version="1.0" name="simple" lifestyle="singleton"
 */
public class HelloComponent extends AbstractLogEnabled 
  implements Initializable, Serviceable, Disposable
{
    RandomGenerator m_random = null;
    Identifiable m_identifiable = 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" );
        m_identifiable = 
          (Identifiable) manager.lookup( Identifiable.class.getName() );
    }

    public void initialize()
    {
        getLogger().info( "initialization" );
        getLogger().info( "received random value: " + m_random.getRandom() );
        getLogger().info( "using identifiable: " + m_identifiable.getIdentity() );
    }

    public void dispose()
    {
        getLogger().info( "disposal" );
    }

}
Declaring the service dependency

In this example we are automatically generating the xinfo descriptors using the builtin meta-info generation goal based on the presence of dependency tags.

* @avalon.dependency type="tutorial.RandomGenerator:1.0"
*    key="random"
* @avalon.dependency type="tutorial.Identifiable"

The generated xinfo for the hello component is shown below.

HelloComponent.xinfo

<type>
  <info>
    <name>simple</name>
    <version>1.0.0</version>
    <lifestyle>singleton</lifestyle>
  </info>
  <dependencies>
    <dependency key="random" type="tutorial.RandomGenerator" version="1.0.0"/>
    <dependency type="tutorial.Identifiable"/>
  </dependencies>
</type>
Executing the demo

Build and run the tutorial.

$ maven
$ merlin target\classes -execute
        

In the logging output we see that Merlin has automatically located both RandomGeneratorProvider and IdentifiableComponent and provided these to the consumer. The HelloComponent implementation has logged the result of accessing and using both services.

[INFO   ] (tutorial.random): initialization
[INFO   ] (tutorial.simple): contextualize
[INFO   ] (tutorial.hello): initialization
[INFO   ] (tutorial.random): processing request
[INFO   ] (tutorial.hello): received random value: 359973592
[INFO   ] (tutorial.hello): using identifiable: /tutorial/simple
[INFO   ] (tutorial.hello): disposal
[INFO   ] (tutorial.random): disposal
Next Topic

The next topic shows how you can override Merlin's automatic dependency resolution by declaring named suppliers for particular dependencies.