Getting Started with OSGi: Registering a Service

Welcome back to the EclipseZone OSGi mini-series. Finally, we're ready to get on to services. In my opinion, the service layer is the most exciting part of OSGi, so these next few installments should be fun.

Last time we looked at the example of a MovieFinder interface, which we said would be used by a MovieLister to search for movies. In fact you may recognize this example -- it is from Martin Fowler's famous paper on "Dependency Injection", also known as "Inversion of Control" or IoC.

Recall the problem that IoC tries to solve. A MovieLister doesn't particularly care where the raw movie data comes from, so we use the MovieFinder interface to hide such details from it. The idea is we can then substitute alternative implementations of MovieFinder , such as one that goes to a database or even one that calls an Amazon Web Service, since MovieLister only depends on the interface, not any particular implementation.

So far so good, but at some point we have to actually give a concrete implementation of MovieFinder to MovieLister . We do this by having an external container "push" a suitable object into it, rather than letting MovieLister go out and call a lookup method. Hence the term "Inversion of Control". Many such containers have been developed, for example PicoContainer, HiveMind, Spring, and even EJB 3.0. However there is one limiting factor of all these containers to date: they are mostly static. Once a MovieFinder is given to a MovieLister , it tends to be associated for the lifetime of the JVM.

OSGi also allows us to implement the IoC pattern, but in a dynamic way. It should be possible to dynamically supply implementations of MovieFinder to MovieLister and later remove them. Then we can hot-swap from an application that looks up movies in a flat text file to an application that looks them up with Amazon Web Services.

It is the Service Layer that helps us do this. Quite simply, we register a MovieFinder as a Service in the Service Registry. Later the MovieLister can be supplied with that MovieFinder Service. A Service therefore is nothing more than a Java object -- a POJO, if you will -- and it is registered under the name of a Java interface (a POJI?).

This time around, we will just look at registering the service with the registry. Later we will look at how to get the service out of the registry and supplied to a MovieLister .

We're going to add the BasicMovieFinder bundle that we built last time. We don't need to modify any existing classes, we just need to add a bundle activator. So copy this into osgitut/movies/impl/BasicMovieFinderActivator.java :


package osgitut.movies.impl;

import org.osgi.framework.*;

import osgitut.movies.*;
import java.util.Properties;
import java.util.Dictionary;

public class BasicMovieFinderActivator implements BundleActivator {
private ServiceRegistration registration;

public void start(BundleContext context) {
MovieFinder finder = new BasicMovieFinderImpl();

Dictionary props = new Properties();
props.put("category", "misc");

registration = context.registerService(
MovieFinder.class.getName(),
finder, props);
}

public void stop(BundleContext context) {
registration.unregister();
}
}



Now replace the content of BasicMovieFinder.mf :

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Basic Movie Finder
Bundle-SymbolicName: BasicMovieFinder
Bundle-Version: 1.0.0
Bundle-Activator: osgitut.movies.impl.BasicMovieFinderActivator
Import-Package: org.osgi.framework,
osgitut.movies;version="[1.0.0,2.0.0)"



There are two things added to this manifest since last time. First is the Bundle-Activator line, which tells the framework about the new activator for our bundle -- we didn't need one last time. Also I have added org.osgi.framework to the imported packages. As our previous version of the bundle didn't interact with the framework, it didn't need to import the OSGi API packages.

Now you can rebuild BasicMovieFinder.jar :

> javac -classpath equinox.jar:MoviesInterface.jar osgitut/movies/impl/*.java
> jar cfm BasicMovieFinder.jar BasicMovieFinder.mf osgitut/movies/impl/*.class


Back in the OSGi console, you should still have BasicMovieFinder.jar installed from last time. So you just need to tell OSGi to update the bundle, by typing update N , where N is the numeric ID of the bundle (which you have found using ss ). Now start the bundle with the command start N and you should see... very little happen.

Actually we've just registered our first service with the OSGi service registry, but unfortunately there's nobody on the "other end", so the registration doesn't produce any visible effect. If we want to reassure ourselves that our code has actually done something, we're going to have to go digging, and we do that with the following command:

services (objectClass=*MovieFinder)


We should see the following output:

{osgitut.movies.MovieFinder}={category=misc, service.id=22}
Registered by bundle: file:BasicMovieFinder.jar [4]
No bundles using service.


Great, our service is registered! And I'd love to go on and tell you how to lookup that service and use it in another bundle, but that will have to wait until another day. In the meantime, see what you can do with the services command. For starters try typing services without the expression in parentheses afterwards -- that was actually a filter which reduced the number of services displayed to just the one we were interested in. Without the filter you will see all of the registered services. There are a surprisingly large number of them!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值