LibraryToggle FramesPrintFeedback

Exporting a Service

Overview

This section describes how to export a Java object to the OSGi service registry, thus making it accessible as a service to other bundles in the OSGi container.

Exporting with a single interface

To export a service to the OSGi service registry under a single interface name, define a service element that references the relevant service bean, using the ref attribute, and specifies the published interface, using the interface attribute.

For example, you could export an instance of the SavingsAccountImpl class under the org.fusesource.example.Account interface name using the blueprint configuration code shown in Example 17.

Example 17. Sample Service Export with a Single Interface

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">

  <bean id="savings" class="org.fusesource.example.SavingsAccountImpl"/>

  <service ref="savings" interface="org.fusesource.example.Account"/>
  
</blueprint>

Where the ref attribute specifies the ID of the corresponding bean instance and the interface attribute specifies the name of the public Java interface under which the service is registered in the OSGi service registry. The classes and interfaces used in this example are shown in Example 18

Example 18. Sample Account Classes and Interfaces

// Java
package org.fusesource.example

public interface Account { ... }

public interface SavingsAccount { ... }

public interface CheckingAccount { ... }

public class SavingsAccountImpl implements SavingsAccount
{
    ...
}

public class CheckingAccountImpl implements CheckingAccount
{
    ...
}

Exporting with multiple interfaces

To export a service to the OSGi service registry under multiple interface names, define a service element that references the relevant service bean, using the ref attribute, and specifies the published interfaces, using the interfaces child element.

For example, you could export an instance of the SavingsAccountImpl class under the list of public Java interfaces, org.fusesource.example.Account and org.fusesource.example.SavingsAccount, using the following blueprint configuration code:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
  <bean id="savings" class="org.fusesource.example.SavingsAccountImpl"/>
  <service ref="savings">
    <interfaces>
      <value>org.fusesource.example.Account</value>
      <value>org.fusesource.example.SavingsAccount</value>
    </interfaces>
  </service>
  ...
</blueprint>
[Note]Note

The interface attribute and the interfaces element cannot be used simultaneously in the same service element. You must use either one or the other.

Exporting with auto-export

If you want to export a service to the OSGi service registry under all of its implemented public Java interfaces, there is an easy way of accomplishing this using the auto-export attribute.

For example, to export an instance of the SavingsAccountImpl class under all of its implemented public interfaces, use the following blueprint configuration code:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
  <bean id="savings" class="org.fusesource.example.SavingsAccountImpl"/>
  <service ref="savings" auto-export="interfaces"/>
  ...
</blueprint>

Where the interfaces value of the auto-export attribute indicates that blueprint should register all of the public interfaces implemented by SavingsAccountImpl. The auto-export attribute can have the following valid values:

disabled

Disables auto-export. This is the default.

interfaces

Registers the service under all of its implemented public Java interfaces.

class-hierarchy

Registers the service under its own type (class) and under all super-types (super-classes), except for the Object class.

all-classes

Like the class-hierarchy option, but including all of the implemented public Java interfaces as well.

Setting service properties

The OSGi service registry also allows you to associate service properties with a registered service. Clients of the service can then use the service properties to search for or filter services. To associate service properties with an exported service, add a service-properties child element that contains one or more beans:entry elements (one beans:entry element for each service property).

For example, to associate the bank.name string property with a savings account service, you could use the following blueprint configuration:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:beans="http://www.springframework.org/schema/beans"
           ...>
  ...
  <service ref="savings" auto-export="interfaces">
    <service-properties>
      <beans:entry key="bank.name" value="HighStreetBank"/>
    </service-properties>
  </service>
  ...
</blueprint>

Where the bank.name string property has the value, HighStreetBank. It is possible to define service properties of type other than string: that is, primitive types, arrays, and collections are also supported. For details of how to define these types, see Controlling the Set of Advertised Properties. in the Spring Reference Guide.

[Note]Note

Strictly speaking, the entry element ought to belong to the blueprint namespace. The use of the beans:entry element in Spring's implementation of blueprint is non-standard.

Default service properties

There are two service properties that might be set automatically when you export a service using the service element, as follows:

  • osgi.service.blueprint.compname—is always set to the id of the service's bean element, unless the bean is inlined (that is, the bean is defined as a child element of the service element). Inlined beans are always anonymous.

  • service.ranking—is automatically set, if the ranking attribute is non-zero.

Specifying a ranking attribute

If a bundle looks up a service in the service registry and finds more than one matching service, you can use ranking to determine which of the services is returned. The rule is that, whenever a lookup matches multiple services, the service with the highest rank is returned. The service rank can be any non-negative integer, with 0 being the default. You can specify the service ranking by setting the ranking attribute on the service element—for example:

<service ref="savings" interface="org.fusesource.example.Account" ranking="10"/>

Specifying a registration listener

If you want to keep track of service registration and unregistration events, you can define a registration listener callback bean that receives registration and unregistration event notifications. To define a registration listener, add a registration-listener child element to a service element.

For example, the following blueprint configuration defines a listener bean, listenerBean, which is referenced by a registration-listener element, so that the listener bean receives callbacks whenever an Account service is registered or unregistered:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" ...>
  ...
  <bean id="listenerBean" class="org.fusesource.example.Listener"/>

  <service ref="savings" auto-export="interfaces">
    <registration-listener
        ref="listenerBean"
        registration-method="register"
        unregistration-method="unregister"/>
  </service>
  ...
</blueprint>

Where the registration-listener element's ref attribute references the id of the listener bean, the registration-method attribute specifies the name of the listener method that receives the registration callback, and unregistration-method attribute specifies the name of the listener method that receives the unregistration callback.

The following Java code shows a sample definition of the Listener class that receives notifications of registration and unregistration events:

// Java
package org.fusesource.example;

public class Listener
{
    public void register(Account service, java.util.Map serviceProperties) {
        ...
    }

    public void unregister(Account service, java.util.Map serviceProperties) {
        ...
    }
}

The method names, register and unregister, are specified by the registration-method and unregistration-method attributes respectively. The signatures of these methods must conform to the following syntax:

  • First method argument—any type T that is assignable from the service object's type. In other words, any supertype class of the service class or any interface implemented by the service class. This argument contains the service instance, unless the service bean declares the scope to be prototype, in which case this argument is null (when the scope is prototype, no service instance is available at registration time).

  • Second method argument—must be of either java.util.Map type or java.util.Dictionary type. This map contains the service properties associated with this service registration.

Comments powered by Disqus