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.
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 10.1.
Example 10.1. 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 10.2
Example 10.2. 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 { ... }
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 | |
---|---|
The |
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.
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 | |
---|---|
Strictly speaking, the |
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 theid
of the service'sbean
element, unless the bean is inlined (that is, the bean is defined as a child element of theservice
element). Inlined beans are always anonymous.service.ranking
—is automatically set, if the ranking attribute is non-zero.
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"/>
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 beprototype
, in which case this argument isnull
(when the scope isprototype
, no service instance is available at registration time).Second method argument—must be of either
java.util.Map
type orjava.util.Dictionary
type. This map contains the service properties associated with this service registration.