本文介绍了用Idea搭建OSGI项目开发的过程,演示使用的JDK8,Equinor OSGI Framework。java
OSGI的全称是Open Service Gateway Initiative,直译就是开放服务网关。最新的OSGI定义是The Dynamic Module System for Java,即面向java的动态模块化系统。
在传统Web开发中,咱们为了进行功能的分离,常常会进行模块划分,好比基础信息模块交由A和B作,接口信息模块交由C和D作。最终,再聚集到一块儿,组成一个完整的项目。在这整一个流程中,咱们作到的只是逻辑上的解耦,最终这些模块仍是运行于同一服务器上,共享同一个classpath。这时就会出现一个局限性问题,好比如今接口规范改了,我只想停掉接口信息模块,而基础信息模块仍能正常运行,这显然是没法实现的。而使用OSGI能够完美解决这个问题,OSGI是基于模块(Bundle)驱动的,每一个模块都有属于本身的classpath和类加载器,模块之间经过服务注册和发现进行关联,每一个模块有着本身独立的生命周期,咱们能够动态地对模块进行加载、卸载、更新。摘自https://www.jianshu.com/p/11d...。
OSGI能够理解成是JVM单进程内的SOA,固然也支持多进程分布式的模块之间的调用。api
下载地址:https://download.eclipse.org/...
本文下载的是equinox-SDK-4.11.zip,下载后进行解压,后面须要用到这个解压目录。服务器
File -> New -> Project,选择Java,点击Next,建立一个空工程。
继续点击Next。
填写项目名称,这里叫osgi_demo。框架
分别建立api、server、client三个OSGI模块。
建立模块时勾选OSGI做为开发环境,Use library从刚才下载的Equinox解压的目录下的plugins目录中选择org.eclipse.osgi_3.13.300.v20190218-1622.jar。
建立模块完成以后,打开idea的preferences,在Languages & Frameworks找到OSGI Framework Instances选项。
添加Equinox,Home directory选择刚才解压的Equinox目录。eclipse
结构以下图
api模块中定义接口类IHelloService分布式
package osgi.demo.api; public interface IHelloService { /** * 和某人打招呼 * @param somebody * @return */ String sayHello(String somebody); }
server模块接口实现类HelloServiceImplide
package osgi.demo.server; import osgi.demo.api.IHelloService; public class HelloServiceImpl implements IHelloService { @Override public String sayHello(String somebody) { return "hello " + somebody; } }
server模块服务注册类HelloServerBundle模块化
package osgi.demo.server; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import osgi.demo.api.IHelloService; import java.util.Dictionary; import java.util.Hashtable; public class HelloServerBundle implements BundleActivator { @Override public void start(BundleContext bundleContext) throws Exception { IHelloService service = new HelloServiceImpl(); Dictionary<String , Object> properties = new Hashtable<>(); //服务注册 bundleContext.registerService(IHelloService.class, service, properties); } @Override public void stop(BundleContext bundleContext) throws Exception { } }
client模块调用服务类HelloClientBundleui
package osgi.demo.client; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import osgi.demo.api.IHelloService; import java.util.Objects; public class HelloClientBundle implements BundleActivator { @Override public void start(BundleContext bundleContext) throws Exception { //获取到IHelloService服务引用 ServiceReference<IHelloService> reference = bundleContext.getServiceReference(IHelloService.class); if (Objects.nonNull(reference)) { //发现服务 IHelloService service = bundleContext.getService(reference); if (Objects.nonNull(service)) { System.out.println(service.sayHello("jecyhw")); } //注销服务 bundleContext.ungetService(reference); } } @Override public void stop(BundleContext bundleContext) throws Exception { } }
api模块配置,导出接口定义所在包osgi.demo.api(Additional properties是bundle的相关属性配置的地方)。
server模块配置,配置HelloServerBundle类做为该bundle的启动类。
client模块配置,配置HelloClientBundle类做为该bundle的启动类。idea
选择Edit Configurations。
添加OSGI Bundles。
配置以下。
client模块调用了server的服务,按照依赖关系,server模块须要先启动,把服务注册在osgi框架中,client模块才能调用到,Start level是用来定义bundle模块的启动优先级,值越小,启动优先级越高。
Framework start level是整个osgi框架的启动级别,也就是整个项目的启动级别,大于这个值的bundle模块是不会被启动的。若是这个值为1,client模块的启动级别为2,client模块是不会被启动的,能够调整试试。
点击OK以后,就能够运行了。
运行结果截图。
Java模块化之路 —— OSGI介绍深刻理解OSGi:Equinox原理、应用与最佳实践