| ServiceBinding-Utils Overview |
|
|
|
ServiceBinding-Utils provides OSGi developers with an API that would allow them to consume OSGi Services by writing the minimum amount of code (mostly it will be 1-3 line of code). The aim of this project is to reduce development time when consuming OSGi services without degrading application's performance or constraining it's design. The solution consists of a single bundle which weighs less than 25 kilobytes and provides ServiceBinding-Utils classes. ServiceBinding-Utils Compared to other Service Binding SolutionsWhen consuming OSGi services I always had to choose between two options:
As for me, when my application already uses Spring, Spring-DM is the natural and simplest way to bind OSGi Services to my objects, but using Spring-DM for the sole purpose of binding service is a resource-inefficient approach. For instance, if I used Spring-DM for every example at DynamicJava.org that consumes OSGi Services then the size of each application would have raised by a little more than 2,5 megabytes, leave aside performance impacts. ServiceBinding-Utils in ActionTo give a better understanding of how ServiceBinding-Utils could simplify your life, below are few examples:
import org.dynamicjava.osgi.service_binding_utils.OsgiServiceBinder;
import org.dynamicjava.osgi.service_binding_utils.ServiceFilter;
import org.dynamicjava.osgi.service_binding_utils.BindingOptions;
import org.dynamicjava.osgi.service_binding_utils.Sorter;
OsgiServiceBinder binder = new OsgiServiceBinder(bundleContext);
/// Consumer1 is a class with a method: void setService(org.test.MyService service)
/// After the bind method is invoked, the binder will look in the OSGi Environment
/// for a service that implements the interface "org.test.MyService" then pass it
/// as a param to the setService method of the Consumer1 class. Each time the
/// service is updated the binder will invoke the setService method. In case
/// multiple services exist that confirm to the condition, the one with highest
/// ranking will be choosen.
Consumer1 consumer1 = new Consumer1();
binder.bind(consumer1, "setService",
ServiceFilter.forInterface("org.test.MyService"));
/// Consumer2 is a class with a method:
/// void setServices(org.test.MyService[] service)
/// The binder will look in the OSGi Environment for services that implement the
/// "org.test.MyService" interface and has a property "serviceType" with value
/// "testService".
Consumer2 consumer2 = new Consumer2();
/// A variant which accepts an LDAP Filter string.
binder.bind(consumer2, "setServices",
ServiceFilter.forInterfaceAndLdapFilter(
"org.test.MyService", "(serviceType=testService)"));
/// Another variant which accepts a service properties dictionary
Dictionary serviceProperties = new Hashtable();
serviceProperties.put("serviceType", "testService");
binder.bind(consumer2, "setServices",
ServiceFilter.forInterfacesAndServiceProperties(
"org.test.MyService", serviceProperties));
/// Consumer3 is a class with one static method:
/// static void setService(org.test.MyService service)
binder.bind(Consumer3.class, "setService",
ServiceFilter.forInterface("org.test.MyService"));
/// Consumer4 is a class with a static method:
/// static void setServices(org.test.MyService[] service)
/// The binder will look in the OSGi Environment for services that implement the
/// "org.test.MyService" interface then it will sort all of the service based
/// on the value of the service property "serviceType" in a descending order.
binder.bind(Consumer4.class, "setServices",
ServiceFilter.forInterface("org.test.MyService"),
new BindingOptions(Sorter.sortBy(false, "serviceType")));
As you can see, binding services to a property (through a setter method), watching service for updates, ranking, filtering, sorting and exception handling is already done for you, so all you have to do is to write 1-3 lines of code. Since the Binder can work with class instances and static methods I can't foresee any design constraints for its usage. How To Use?To use ServiceBinding-Utils you need to:
ExampleThe example consists of an API Bundle that provides service interfaces, 2 Service Provider Bundles that provides services that implement the interfaces in the API bundle and a Service Consumer Bundle which consumes the services using ServiceBinding-Utils. Consumer classes invoke the services they are bound to every 2 seconds so you could uninstall and install Service Provider Bundles at runtime and see consumers' reaction. service-binding-utils-example.zip |