运行环境

配置好Java这些基础环境就忽略了。

下载Felix

假设下载到~/Downloads目录,然后解压

cd ~/Downloads
tar -xvf org.apache.felix.main.distribution-5.2.0.tar.gz
cd felix-framework-5.2.0

启动OSGi运行环境:

➜  felix-framework-5.2.0  java -jar bin/felix.jar
____________________________
Welcome to Apache Felix Gogo

g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.2.0)
    1|Active     |    1|Apache Felix Bundle Repository (2.0.4)
    2|Active     |    1|Apache Felix Gogo Command (0.14.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)
g!

服务的生命周期监听器例子

example1

打开eclipse,File–> New –> Project –> Plug-in Project –> 填写项目名 –> Target Platform 里选择 an OSGi framework -->standard`.最后一步创建模板时,选择空,即不选择任何模板。

创建成功后,修改MANIFEST.MF文件相应内容,比如Version等,然后创建一个类,内容如下:

package example1;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;

public class Activator implements BundleActivator, ServiceListener {

	private static BundleContext context;

	static BundleContext getContext() {
		return context;
	}

	public void start(BundleContext bundleContext) throws Exception {
		Activator.context = bundleContext;
		Activator.context.addServiceListener(this);
		System.out.println("启动Bundle");
	}

	public void stop(BundleContext bundleContext) throws Exception {
		Activator.context.removeServiceListener(this);
		Activator.context = null;
		System.out.println("停止Bundle");
	}

	@Override
	public void serviceChanged(ServiceEvent event) {
		String[] objectClass = (String[]) event.getServiceReference().getProperty("objectClass");
		if (event.getType() == ServiceEvent.REGISTERED) {
			System.out.println("服务类型为: " + objectClass[0] + " 已经注册.");
		} else if (event.getType() == ServiceEvent.UNREGISTERING) {
			System.out.println("服务类型为: " + objectClass[0] + " 已经取消注册.");
		} else if (event.getType() == ServiceEvent.MODIFIED) {
			System.out.println("服务类型为: " + objectClass[0] + " 已经修改.");
		}
	}

}

然后File –> Export –> Plug-in Development –> Deployable plug-ins and fragments –> Directory 选择到Felix的bundle目录里。 可以看到目录内容如下:

➜  bundle  ls
Example1_1.0.0.jar
org.apache.felix.bundlerepository-2.0.4.jar
org.apache.felix.gogo.command-0.14.0.jar
org.apache.felix.gogo.runtime-0.16.2.jar
org.apache.felix.gogo.shell-0.10.0.jar
➜  bundle

我们的Bundle, Example1_1.0.0.jar 已经准备好了。接下来就是安装这个Bundle

安装bundle

➜  felix-framework-5.2.0  java -jar bin/felix.jar
____________________________
Welcome to Apache Felix Gogo

g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.2.0)
    1|Active     |    1|Apache Felix Bundle Repository (2.0.4)
    2|Active     |    1|Apache Felix Gogo Command (0.14.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)
g! start file:/home/yang/Downloads/felix-framework-5.2.0/bundle/Example1_1.0.0.jar
启动Bundle
g!

可以看到,打印出了启动Bundle的输出。

停止Bundle

➜  felix-framework-5.2.0  java -jar bin/felix.jar
____________________________
Welcome to Apache Felix Gogo

g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.2.0)
    1|Active     |    1|Apache Felix Bundle Repository (2.0.4)
    2|Active     |    1|Apache Felix Gogo Command (0.14.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)
g! start file:/home/yang/Downloads/felix-framework-5.2.0/bundle/Example1_1.0.0.jar
启动Bundle
g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.2.0)
    1|Active     |    1|Apache Felix Bundle Repository (2.0.4)
    2|Active     |    1|Apache Felix Gogo Command (0.14.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)
    5|Active     |    1|Example1 (1.0.0)
g! stop 5
停止Bundle
g!

这个只是服务的监听器类,下面创建一个新的服务项目,用来注册某种服务。

Example2

服务接口如下:

package example2.service;

public interface SayHelloService {
	public String say(String name);
}

服务实现接口如下:

package example2;

import java.util.Hashtable;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

import example2.service.SayHelloService;

public class Activator implements BundleActivator {

	private static BundleContext context;

	static BundleContext getContext() {
		return context;
	}

	public void start(BundleContext bundleContext) throws Exception {
		Activator.context = bundleContext;
		Hashtable<String, String> props = new Hashtable<String, String>();
		props.put("Language", "English");
		context.registerService(SayHelloService.class.getName(), new SayHelloImpl(), props);
	}

	public void stop(BundleContext bundleContext) throws Exception {
		Activator.context = null;
	}

	private static class SayHelloImpl implements SayHelloService {

		@Override
		public String say(String name) {
			return "from say hello impl: " + name;
		}

	}

}

然后以同样的方式,导出到Felix的bundle目录。然后启动:

g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.2.0)
    1|Active     |    1|Apache Felix Bundle Repository (2.0.4)
    2|Active     |    1|Apache Felix Gogo Command (0.14.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)
    6|Resolved   |    1|Example1 (1.0.0)
    7|Active     |    1|Example2 (1.0.0)
g! stop 7
g! start 6
启动Bundle
g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.2.0)
    1|Active     |    1|Apache Felix Bundle Repository (2.0.4)
    2|Active     |    1|Apache Felix Gogo Command (0.14.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)
    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)
    6|Active     |    1|Example1 (1.0.0)
    7|Resolved   |    1|Example2 (1.0.0)
g! start 7
服务类型为: example2.service.SayHelloService 已经注册.
g!

这样,就完成了服务注册及其监听器的小例子了。开启OSGi之路吧!