Vous pouvez créer un objet et l'enregistrer en tant que
service OSGi en vue de son utilisation par des fonctions tierces.
Pourquoi et quand exécuter cette tâche
A l'aide d'un code Java ancien simple, vous pouvez créer un objet, puis l'enregistrer en tant que service avec la classe BundleContext.
Etant donné que le code doit s'exécuter, l'enregistrement de l'objet est généralement effectué dans une interface BundleActivator. Lorsque vous enregistrez l'objet, vous pouvez spécifier les interfaces qu'il met à disposition et fournir une mappe de propriétés. Un objet ServiceRegistration est renvoyé ; si nécessaire, vous pouvez l'utiliser pour changer les propriétés à tout moment. Une fois l'exécution du service terminée, vous utilisez l'objet ServiceRegistration pour annuler son enregistrement.
Pour obtenir un service, vous recherchez dans BundleContext un service qui implémente une interface requise et en option, fournissez un filtre de syntaxe LDAP pour mettre en correspondance les propriétés de service. Selon la méthode que vous appelez, vous pouvez extraire la meilleure correspondance, ou toutes les correspondances.
Vous pouvez ensuite utiliser l'objet ServiceReference qui fournit les propriétés pour une correspondance plus avancée dans votre code. Vous pouvez utiliser l'objet ServiceReference pour obtenir l'objet de service réel. Une fois que vous avez terminé d'utiliser le service, vous utilisez BundleContext pour le libérer.
- Déclarez l'interface de service en ajoutant le code suivant dans votre bundle :
package com.ibm.foo.simple;
/**
* Our multifunctional sample interface
*/
public interface Foo
{
}
- Spécifiez le code d'implémentation de l'interface.
package com.ibm.foo.simple;
/**
* The implementation of the Foo interface
*/
public class FooImpl implements Foo
{
public FooImpl()
{
}
public FooImpl(String vendor)
{
}
/**
* used by the ServiceFactory implementation.
*/
public void destroy() {
}
}
- Utilisez BundleContext pour enregistrer le service, modifier les propriétés de service et annuler l'enregistrement du service directement dans votre code.
import java.util.Dictionary;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
/**
* Registers and unregsiters a Foo service directly,
* and shows how to modify the service properties in code.
*/
public class FooController
{
private final BundleContext bundleContext;
private ServiceRegistration<Foo> sr;
public FooController( BundleContext bundleContext )
{
this.bundleContext = bundleContext;
}
public void register(Dictionary<String, Object> serviceProperties) {
Foo foo = new FooImpl();
//typed service registration with one interface
sr = bundleContext.registerService( Foo.class, foo, serviceProperties );
//or
//untyped service registration with one interface
sr = (ServiceRegistration<Foo>)bundleContext.registerService(
Foo.class.getName(), foo, serviceProperties );
//or
//untyped service registration with more than one interface (or class)
sr = (ServiceRegistration<Foo>)bundleContext.registerService(new String[] {
Foo.class.getName(), FooImpl.class.getName()}, foo, serviceProperties );
}
public void modifyFoo(Dictionary<String, Object> serviceProperties) {
//with the service registration you can modify the service properties at any time
sr.setProperties( serviceProperties );
}
public void unregisterFoo() {
//when you are done unregister the service using the service registration
sr.unregister();
}
}
- Obtain and return the service from another class:
package com.ibm.foo.simple;
import java.util.Collection;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
/**
* A simple Foo client that directly obtains the Foo service and returns it when done.
*/
public class FooUser
{
private final BundleContext bundleContext;
public FooUser( BundleContext bundleContext )
{
this.bundleContext = bundleContext;
}
/**
* assume there's only one Foo
*/
public void useFooSimple() {
ServiceReference<Foo> sr = bundleContext.getServiceReference( Foo.class );
String[] propertyKeys = sr.getPropertyKeys();
for (String key: propertyKeys) {
Object prop = sr.getProperty( key );
//think about whether this is the Foo we want....
}
Foo foo = bundleContext.getService( sr );
try {
//use foo
} finally {
//we're done
bundleContext.ungetService( sr );
}
}
/**
* Use a filter to select a particular Foo. Note we get a collection back and have to pick one.
* @throws InvalidSyntaxException
*/
public void useFooFilter() throws InvalidSyntaxException {
Collection<ServiceReference<Foo>> srs = bundleContext.getServiceReferences(
Foo.class, "(&(service.vendor=IBM)(id='myFoo')" );
ServiceReference<Foo> sr = srs.iterator().next();
String[] propertyKeys = sr.getPropertyKeys();
for (String key: propertyKeys) {
Object prop = sr.getProperty( key );
//think about whether this is the Foo we want....
}
Foo foo = bundleContext.getService( sr );
try {
//use foo
} finally {
//we're done
bundleContext.ungetService( sr );
}
}
}