最近在看tomcat源码,看到的osgi这个东东,一脸懵逼。这里做下记录。
osgi介绍
osgi,英文全称(Open Service Gateway Initiative)就是动态模块化系统,它能在运行时更新相关的模块,也就是热插拔。osgi是一个规范,并不是一个实现,目前OSGi规范的主流实现框架有Eclipse Equinox以及Apache Felix。在osgi中把模块称为bundle。每个bundle有自己的类加载器。每个bundle都有一个/META-INF/MANIFEST.MF,其中包括了bundle的一些信息(例如暴露给其他bundle的包,启动器等)。它比较适合需求变更比较频繁,扩展需求比较高的应用。
使用felix创建最基础的模块化项目
导入felix maven依赖:
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.osgi.core</artifactId>
<version>1.4.0</version>
<scope>provided</scope>
</dependency>
导入生成/META-INF/MANIFEST.MF的插件:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.4.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${pom.groupId}.${pom.artifactId}</Bundle-SymbolicName>
<Bundle-Vendor>Apache Felix</Bundle-Vendor>
<Bundle-Activator>org.hhb.osgi.consumer.HelloWorldActivator</Bundle-Activator> //启动器
</instructions>
</configuration>
</plugin>
接下来写我们的启动器代码。
实现BundleActivator
接口,为其他bundle提供服务
import org.hhb.osgi.provider.api.HelloWorldService;
import org.hhb.osgi.provider.impl.HelloWorldServiceImpl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
public class HelloActivator implements BundleActivator {
private ServiceRegistration registration;
@Override
public void start(BundleContext bundleContext) throws Exception {
registration = bundleContext.registerService(
HelloWorldService.class.getName(),
new HelloWorldServiceImpl(),
null);//注册一个服务供其他bundle使用
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
registration.unregister();
}
}
实现BundleActivator
接口消费上面注册的服务
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.hhb.osgi.provider.api.HelloWorldService;
public class HelloWorldActivator implements BundleActivator {
private HelloWorldConsumer consumer;
@Override
public void start(BundleContext bundleContext) throws Exception {
ServiceReference reference = bundleContext.getServiceReference(HelloWorldService.class.getName());
consumer = new HelloWorldConsumer((HelloWorldService) bundleContext.getService(reference));
consumer.startTimer();
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
consumer.stopTimer();
}
}
felix的使用
上面我们只是在写模块,还没有启动,那如何启动这些bundle呢?就需要felix环境。下面我们就讲下felix。
-
到官网下载Felix Framework Distribution。
-
解压felix,进入felix目录,使用以下命令运行felix:
java -jar bin/felix.jar
这样felix就启动了。
下面介绍下felix的几个基本命令:
-
lb
查看所有的bundle的信息 -
install XXX.jar
安装某个bundle。此操作会反回一个数字,应该就是服务的id
-
start 1
启动id为1的服务,对应了上面BundleActivator
中的start
方法 -
stop 1
关闭id为1的服务,对应了上面BundleActivator
中的stop
方法 -
uninstall 1
卸载id为1的服务 -
update 1
更新id为1的服务。如果依赖的bundle更改了,可以使用该命令来更新服务。这里应该就体现了热插拔吧(个人理解)
以上内容如有不足之处,请各位大侠指点。
网友评论