OSGI入门实例讲解(一)

架构师之路 - 利用Qt实现OSGi框架 当然,Qt实现的OSGi框架只是一个简单的示例,仅供学习交流之用,如果需要在实际生产环境中使用,请考虑使用更成熟和稳定的C++框架。与Calculator类类似,我们在Printer类的构造函数中设置了Bundle的名称和版本号,并将print方法作为服务"printer:print"注册到了ServiceRegistry中。当一个服务被成功注册或卸载时,它会发出相应的信号。在C++开发领域中,虽然没有类似Java中的OSGi实现框架,但是我们可以利用Qt的信号与槽机制实现一个具有类似功能的框架。 阅读详情

开放服务网关倡议(OSGi)定义了开发和部署模块应用程序和库的体系结构。作为介绍OSGi的第一篇文章,本文旨在让你了解OSGi开发的一些概念,并向你展示了如何使用Eclipse的OSGi容器(Equinox)实现建立一个简单的Hello World应用。此外还简要介绍了使用OSGi构建面向服务的应用程序以及OSGi的servicefactory和servicetracker类。

OSGI(Open Services Gateway Initiative),也叫JAVA动态模块系统,定义了一套模块应用开发的框架。OSGI容器的实现方案如Knopflerfish, Equinox, and Apache Felix允许你将应用分成多个功能模块,从而更方便地管理它们之间的相互依赖性。

和Servlet和EJB规范类似,OSGI规范定义了两件事:一个OSGI容器需要实现的服务集合;一种OSGI容器和应用之间通信的机制。开发OSGI平台意味着你需要使用OSGI API编写你的应用,然后将其部署到OSGI容器中。从开发者的视角来看,OSGI提供以下优势:

  1. 你可以动态地安装、卸载、启动、停止不同的应用模块,而不需要重启容器。
  2. 你的应用可以在同一时刻运行同一个模块的多个版本。
  3. OSGI在SOA领域提供成熟的解决方案,包括嵌入式,移动设备和富客户端应用等。

现在,你已经有个Servlet容器来做web 应用,有了EJB容器来做事务处理,你可能在想为什么你还需要一个新的容器?简单点说,OSGI容器被设计专门用来开发可分解为功能模块的复杂的Java应用。

企业应用领域的OSGI

OSGI规范最初是由OSGI联盟在1999年3月发起。它的主要目的是成为向网络设备传输服务管理的开放规范。核心思想是一旦你向网络设备中添加了一个OSGI服务平台,你可以在网络中的任意位置管理该设备上的服务组件。这些服务组件可以任意安装,更新或移除而不会对设备产生影响。

多年来,OSGI技术只出现在嵌入式系统和网络设备市场。现在,Eclipse使OSGI在企业开发领域焕发出新的光彩。

OSGI受到越来越广泛的支持

2003年,Eclipse开发团队开始寻找一种使eclipse成为一种功能更动态、工具更模块化的富客户端平台。最终,他们的目光锁定在OSGI框架上。Eclipse3.0,2004年6月发布,是基于OSGI技术搭建的首个Eclipse版本。

几乎所有企业应用服务提供商支持或计划支持OSGI。Spring框架同样支持OSGI,通过Spring DM(Spring Dynamic Modules for OSGI Service Platforms)项目,可以让我们在Spring上更方便的应用OSGI。

开源OSGI容器

从企业应用开发者的角度看,OSGI容器侵入性非常小,你可以方便地将其嵌入一个企业应用。举个例子来说,假设你在开发一个复杂的web应用。你希望将这个应用分解成多个功能模块。一个View层模块,一个Model层模块,一个DAO模块。使用嵌入式OSGI容器来跨依赖地管理这些模块可以让你随时更新你的DAO模块却不需要重启你的服务器。

只要你的应用完全符合OSGI规范,它就可以在所有符合OSGI规范的容器内运行。现在,有三种流行的开源OSGI容器:

  1. Equinox是OSGI Service Platform Release 4的一个实现。是Eclipse 模块化运行时的核心。
  2. Knopflerfish另一个选择。
  3. Apache Felix是Apache软件基金会赞助的一个OSGI容器

在这篇文章里我们使用Equinox作为我们的OSGI容器。

尝试开发一个Hello World bundle

在OSGI的领域,发布的软件是以bundle的形式出现。bundle由java class类和资源文件组成,向设备所有者提供功能,同时可以为其他的bundles提供服务。Eclipse对开发bundles提供了强大的支持。Eclipse不仅仅提供创建bundles的功能,它还集成了Equinox这个OSGI容器,你可以在其上开发和调试OSGI组件。其实所有的Eclipse插件都是使用Eclipse规范代码写的OSGI bundle。接下来,你将可以学到如何使用Eclipse IDE开发一个Hello world osgi bundle。

开始开发bundle

我们一步步的开始:

  1. 启动Eclipse,依次点 File --> New --> Project。
  2. 选择Plug-in Project,next。
  3. 输入Project Name项目名称,比如com.xjtu.cruise.sample.HelloWorld,Target Platform(目标平台)里的an OSGI framework,选择standard。
  4. 剩下的保持默认,next。
  5. 下个对话框也默认,next。
  6. 然后选择Hello OSGI Bundle作为模版。Finish。

Eclipse会飞快的为你创建Hello world bundle的模版代码。主要包含两个文件:Activator.java和MANIFEST.MF。

Activator.java的代码如下所示:

package com.xjtu.cruise.sample.helloworld;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
    public void start(BundleContext context) throws Exception {
        System.out.println("Hello world");
    }
    public void stop(BundleContext context) throws Exception {
        System.out.println("Goodbye World");
    }
}
如果你的bundle在启动和关闭的时候需要被通知,你可以考虑实现BundleActivator接口。以下是定义Activator的一些注意点:

  1. 你的Activator类需要一个公有的无参数构造函数。OSGI框架会通过类反射的方式来实例化一个Activator类。
  2. 容器启动bundle过程中负责调用你的Activator类的start方法。bundle可以在此初始化资源比如说初始化数据库连接。start方法需要一个参数,BundleContext对象。这个对象允许bundles以取得OSGI容器相关信息的方式和框架交互。如果某一个bundle有异常抛出,容器将对该bundle标记为stopped并不将其纳入service列表。
  3. 容器关闭的时候会调用你的Activator类方法stop(),你可以利用这个机会做一些清理的操作。

MANIFEST.MF

这个文件是你的bundle的部署描述文件。格式和Jar里的MANIFEST.MF是一样的。包含的不少名值对,就像如下:

Manifest-Version: 1.0  
Bundle-ManifestVersion: 2  
Bundle-Name: HelloWorld Plug-in  
Bundle-SymbolicName: com.xjtu.cruise.sample.HelloWorld  
Bundle-Version: 1.0.0  
Bundle-Activator: com.xjtu.cruise.sample.helloworld.Activator  
Bundle-Vendor: HOWARD  
Bundle-RequiredExecutionEnvironment: JavaSE-1.6  
Import-Package: org.osgi.framework;version="1.3.0"

分别来看下:

Bundle-ManifestVersion

数值为2意味着本bundle支持OSGI规范第四版;如果是1那就是支持OSGI规范第三版。

Bundle-Name

给bundle定义一个短名,方便人员阅读

Bundle-SymbolicName

给bundle定义一个唯一的非局部名。方便分辨。

Bundle-Activator

声明在start和stop事件发生时会被通知的监听类的名字。

Import-Package

定义bundle的导入包。

Hello World bundle完成了,接下来我们运行一下。

执行bundle

  1. 点击Run --> Run Configuration
  2. 在左边的OSGI Framework选项里右键 new ,创建一个新的OSGI Run Configuration
  3. 名字随便取好了,我们取个OSGi hello world。
  4. 你会注意到中间的窗口里Workspace项目里有一子项 com.howard.sample.HelloWorld,将其勾选上,其他的不用管。这时的状态应该如下图。
  5. 点击Run按钮。在控制台你应该可以看见点东西了。那是叫做OSGI控制台的东东。与子相伴,还有一个"Hello world"。


OSGI控制台

OSGI控制台是一个OSGI容器的命令行界面。你可以利用它做些诸如启动,关闭,安装bundles,更新和删除bundles等操作。现在,点击OSGI控制台所在的位置,回车,你就会发现可以输入命令了。这时的OSGI控制台应该如下图:

依赖管理

OSGI规范允许你把你的应用分解成多个模块然后管理各个模块间的依赖关系。

这需要通过bundle scope来完成。默认情况下,一个bundle内的class对其他bundle来说是不可见的。那么,如果要让一个bundle访问另一个bundle里的class要怎么做?解决的方案就是从源bundle导出包,然后在目标bundle里导入。

接下来我们对此做一个例子。

首先,我们需要先创建一个com.xjtu.cruise.sample.HelloService bundle,我们将通过它导出一个包。

然后,我们在com.xjtu.cruise.sample.HelloWorld 这个bundle里导入包。

导出包

1、创建名为com.xjtu.cruise.sample.HelloService的bundle,创建步骤和前面一样。

2、在这个bundle内,添加一个com.xjtu.cruise.sample.service.HelloService.java 接口,代码如下:

public interface HelloService {
    public String sayHello();
}
3、创建一个com.xjtu.cruise.sample.service.impl.HelloServiceImpl.java类实现刚才的接口:
public class HelloServiceImpl implements HelloService{
    public String sayHello() {
        System.out.println("Inside HelloServiceImple.sayHello()");
        return "Say Hello";
    }
}
4、打开MANIFEST.MF,选择Runtime标签项,在Exported Packages选项栏,点击Add并且选择com.xjtu.cruise.sample.service这个包。然后MANIFEST.MF的代码应该如下:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: HelloService
Bundle-SymbolicName: com.xjtu.cruise.sample.HelloService
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.xjtu.cruise.sample.Activator
Bundle-Vendor: XJTU
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: org.osgi.framework;version="1.3.0"
Export-Package: com.xjtu.cruise.sample.service

你可以看到,MANIFEST.MF文件和刚才的HelloWorld的那份很类似。唯一的区别就是这个多了Export-Package这个标记,对应的值就是我们刚才选择的om.xjtu.cruise.sample.service

Export-Package标记告诉OSGI容器在com.xjtu.cruise.sample.service包内的classes可以被外部访问。

注意,我们仅仅暴露了HelloService接口,而不是直接暴露HelloServiceImpl实现。

导入包

接下来我们要更新原来的HelloWorld bundle以导入com.howard.sample.service包。步骤如下:

 1、进入HelloWorld bundle,打开MANIFEST.MF,进入Dependencies标签页,在Imported Packages里添加com.howard.sample.service。MANIFEST.MF文件应该如下所示:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: HelloWorld
Bundle-SymbolicName: com.xjtu.cruise.sample.HelloWorld
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.xjtu.cruise.sample.helloworld.Activator
Bundle-Vendor: XJTU
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: com.xjtu.cruise.sample.service,
org.osgi.framework;version="1.3.0"

没错,Import-package标记的值也就是导入的包名之间是用逗号隔开的。在这里导入了两个包com.xjtu.cruise.sample.service和org.osgi.framework。后者是使用Activator类时必须导入的包。

2、接下来,打开HelloWorld项目下的Activator.java文件,这时候你会发现可以使用HelloService这个接口了。但还是不能使用HelloServiceImpl实现类。Eclipse会告诉你:Access restriction(立入禁止)。

Class级别可见域

为什么OSGI容器可以做到让jar包中的一些classes可见而另一些又不可见呢。

答案其实就是OSGI容器自定义了java class loader来有选择的加载类。OSGI容器为每一个bundle都创建了不同的class loader。因此,bundle可以访问的classes包括

  • Boot classpath:所有的java基础类。
  • Framework classpath:OSGI框架级别的classloader加载的类
  • Bundle classpath:Bundle本身引用的关系紧密的JAR的路径
  • Imported packages:就是在MANIFEST.MF里声明的导入包,一旦声明,在bundle内就可见了。

bundle级别的可见域允许你可以随时放心的更改HelloServiceImpl实现类而不需要去担心依赖关系会被破坏。

OSGI服务

OSGI框架是实现SOA的绝佳土壤。通过它可以实现bundles暴露服务接口给其他bundles消费而不需要让细节暴露。消费bundles甚至可以完全不知道提供服务的bundles。凭着可以良好的隐藏具体实现的能力,OSGI当之无愧是SOA的一种较完美的实现方案。

OSGI中,提供服务的bundle在OSGI容器上将一个POJO注册成一个service。消费者bundle请求OSGI容器中基于某个特殊接口的注册service。一旦找到,消费者bundle就会绑定它,然后就可以调用service中的方法了。举个例子会更容易说明。

导出services

1、确保com.xjtu.cruise.sample.HelloService里的MANIFEST.MF导入org.osgi.framework包

2、创建com.xjtu.cruise.sample.service.impl.HelloServiceActivator.java,代码如下:

public class HelloServiceActivator implements BundleActivator {
	ServiceRegistration helloServiceRegistration;
	@Override
	public void start(BundleContext context) throws Exception {
		HelloService helloService = new HelloServiceImpl();
		helloServiceRegistration = context.registerService(HelloService.class
				.getName(), helloService, null);
	}

	@Override
	public void stop(BundleContext context) throws Exception {
		helloServiceRegistration.unregister();
	}

}

OK,我们就是用BundleContext的registerService方法注册service的。这个方法需要三个参数。

  • service的接口名。如果service实现了多个接口,那样你需要传入一个包含所有接口名的String数组。在这里我们传入的是HelloService这个接口。
  • 真正的service实现。在例子中我们传了一个HelloServiceImpl实现。
  • service属性。这个参数可以在有多个service实现同一个接口的情况下,消费者用来区分真正感兴趣的service。

3、最后一步就是修改HelloService的MANIFEST.MF文件,将Bundle-Activator改成com.xjtu.cruise.sample.service.impl.HelloServiceActivator

现在HelloService bundle已经随时准备将HelloServiceImpl服务发布了。OSGI容器启动HelloServie bundle的时候会让HelloServiceActivator运作,在那个时候将HelloServiceImpl注册到容器中,接下来就是创建消费者的问题了。

导入service

我们的消费者就是HelloWorld bundle,主要修改的就是其中的Activator.java,修改代码如下:

public class Activator implements BundleActivator {
ServiceReference helloServiceReference;
	public void start(BundleContext context) throws Exception {
		System.out.println("Hello World!!");
		helloServiceReference=context.getServiceReference(HelloService.class.getName());
		HelloService helloService=(HelloService)context.getService(helloServiceReference);
		System.out.println(helloService.sayHello());
	}
	public void stop(BundleContext context) throws Exception {
		System.out.println("Goodbye World!!");
		context.ungetService(helloServiceReference);
	}
}

代码很简单,就不多说了。

在运行之前我们在Run-->Run Configurations对话框里,把HelloWorld和HelloService这两个bundle前面的钩都打上。然后运行时你会发现HelloServiceImpl.sayHello()方法已经被调用了。

在OSGI控制台输入ss并回车,所有容器内的bundle状态一目了然。其中id为0的bundle是OSGI框架基础bundle,另两个就是HelloService和HelloWorld了,它俩的id是随机的,状态是ACTIVE也就是已启动状态。假设HelloService的id为7,HelloWorld为8。

输入stop 8就可以暂停bundle的运行,容器内这个bundle还是存在的,只是状态变成了RESOLVED。再次启动使用start 8,然后就会看见HelloWorld bundle消费了HelloService的服务。

创建服务工厂

刚才例子所示,我们会在HelloService bundle启动时初始化并注册service。然后不管存不存在消费端,这个service都会存在,而且消费端取得的service 实例其实都是同一个。OK,现在我们想让Service bundle为每一个consumer bundle返回不同的HelloService bundle实例,又或者某些servie是比较耗费资源的主(如数据库连接),我们不希望它一直占用资源,最好是在真正用它的时候再去创建,不用的时候销毁就最好了。

解决如上问题的方案就是使用ServiceFactory接口的实现来代替原先service具体的实现到OSGI容器去注册。这样,以后只有当其他bundle请求该服务时,才会由ServiceFactory实现类来处理请求并返回一个新的service实例。

实例步骤如下:

1、在HelloService bundle创建一个实现ServiceFactory接口的类HelloServiceFactory类,代码如下:

public class HelloServiceFactory implements ServiceFactory {
    private int usageCounter = 0;
    @Override
    public Object getService(Bundle bundle, ServiceRegistration registration) {
        System.out.println("Create object of HelloService for " + bundle.getSymbolicName());
        usageCounter++;
        System.out.println("Number of bundles using service " + usageCounter);
        HelloService helloService = new HelloServiceImpl();
        return helloService;
    }
    @Override
    public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
        System.out.println("Release object of HelloService for " + bundle.getSymbolicName());
        usageCounter--;
        System.out.println("Number of bundles using service " + usageCounter);
    }
}

ServiceFactory接口定义了两个方法:

  • getService方法:特定的bundle在第一次调用BundleContext的getService方法时由OSGI框架调用,在实例代码中,我们用这个方法来返回一个新的HelloService的实现。OSGI框架会缓存这个返回的对象,如果同一个bundle在未来再次调用BundleContext的getService方法的话,会直接返回这个缓存中的对象。
  • ungetService方法:bundle释放service的时候由OSGI容器调用。

2、修改HelloServiceActivator.java的start方法,将ServiceFactory作为服务注册,代码如下:

public class HelloServiceActivator implements BundleActivator {
	ServiceRegistration helloServiceRegistration;
	@Override
	public void start(BundleContext context) throws Exception {
		HelloServiceFactory helloServiceFactory = new HelloServiceFactory();
		helloServiceRegistration = context.registerService(HelloService.class
				.getName(), helloServiceFactory, null);
	}

	@Override
	public void stop(BundleContext context) throws Exception {
		helloServiceRegistration.unregister();
	}
}
现在运行下试试看,你会发现HelloWorld bundle启动时才会初始化HelloService,控制台会打印出"Number of bundles using service 1",当HelloWorld bundle暂停时会打印出"Number of bundles using service 0"。

services跟踪

某种情形下,我们可能需要在某个特殊的接口有新的服务注册或取消注册时通知消费端。这时我们可以使用ServiceTracker类。如下步骤所示:

1、在HelloWorld bundle里的MANIFEST.MF导入org.osgi.util.tracker包。

2、创建HelloServiceTracker类,代码如下:

public class HelloServiceTracker extends ServiceTracker {
    public HelloServiceTracker(BundleContext context) {
        super(context, HelloService.class.getName(),null);
    }
    public Object addingService(ServiceReference reference) {
        System.out.println("Inside HelloServiceTracker.addingService " + reference.getBundle());
        return super.addingService(reference);
    }
    public void removedService(ServiceReference reference, Object service) {
        System.out.println("Inside HelloServiceTracker.removedService " + reference.getBundle());
        super.removedService(reference, service);
    }
}

我们在HelloServiceTracker的构造函数里将HelloService接口名传进去,ServiceTracker会跟踪实现这个接口的所有的注册services。ServiceTracker主要有两个重要方法:

  • addingService方法:bundle注册一个基于给定接口的service时调用。
  • removeService方法:bundle取消注册一个基于给定接口的service时调用。
3、修改Activator类,使用刚刚创建的HelloServiceTracker来获取service:

public class Activator implements BundleActivator {
	HelloServiceTracker helloServiceTracker;
	public void start(BundleContext context) throws Exception {
		System.out.println("Hello World!!");
		helloServiceTracker= new HelloServiceTracker(context);
		helloServiceTracker.open();
		HelloService helloService=(HelloService)helloServiceTracker.getService();
		System.out.println(helloService.sayHello());
	}
	
	public void stop(BundleContext context) throws Exception {
		System.out.println("Goodbye World!!");
		helloServiceTracker.close();
	}
}

现在运行一下,可以发现只要HelloService bundle启动或是暂停都会导致HelloServiceTracker的对addingService或removedService方法的调用。

ServiceTracker不仅仅能跟踪Service的动向,它还能通过getService方法取得Service实例并返回。但是如果同一个接口下有多个service注册,这时返回哪个service呢?这时候就需要看service的等级哪个高了。这个等级是service注册时的property属性里的一项:SERVICE_RANKING。谁的SERVICE_RANKING高,就返回谁。

如果有两个一样高的呢?这时再看这两个service谁的PID更低了。

OSGI OSGI osgi框架 eclipse插件 soa Bundle Activator OSGI OSGI osgi框架 eclipse插件 soa Bundle Activator OSGI OSGI osgi框架 eclipse插件 soa Bundle Activator OSGI OSGI osgi框架 eclipse插件 soa Bundle Activator OSGI OSGI osgi框架 eclipse插件 soa Bundle Activator


3、OSGi 入门指南:架构、服务与实践 本文是一篇关于OSGi架构、服务与实践的入门指南,详细介绍了OSGi框架的多个层次,包括安全层、模块层、生命周期层和服务层。内容涵盖了OSGi服务接口、服务注册与发现机制、业务服务示例以及与框架服务的协同工作方式。此外,文章还指导如何编写一个简单的OSGi Hello World应用程序,并探讨了模块化设计原则、错误处理、日志记录和性能优化的最佳实践。最后,总结了OSGi在大型分布式系统、物联网和云计算领域的重要性。 阅读详情

相关推荐

OSGi实战教程:从入门到项目实战

本文还有配套的精品资源,点击获取 简介:OSGi实战是一本入门教程,通过理论与实践相结合的方式,帮助读者掌握OSGi的核心概念和技术。它介绍了OSGi的基本原理,如模块化系统和服务导向架构。实战部分深入讲解如何创建和配置OSGi Bundle,使用流行的运行时环境和编写MANIFEST.MF文件。代码实例部分提供了实际的OSGi项目开发示例,涵盖了服务创建、依赖处理和版本控...

weixin_32999557的博客 1983

人人都会OSGI--实例讲解OSGI开发

/** *  转载请注明作者longdick    http://longdick.iteye.com * */     OSGI(Open Services Gateway Initiative),或者通俗点说JAVA动态模块系统,定义了一套模块应用开发的框架。OSGI容器实现方案如Knopflerfish, Equinox, and Apache Felix允许...

幸福的懦夫 3296

OSGi框架入门实战:HelloWorld实例详解

OSGi(Open Service Gateway Initiative)是一种面向Java的模块化框架,旨在实现应用程序的动态模块化管理。它通过定义清晰的模块(Bundle)边界与依赖机制,提升系统的可维护性与可扩展性。自1999年提出以来,OSGi逐步成为企业级Java模块化开发的事实标准。本章将引导你通过一个简单的HelloWorld程序,理解OSGi的基本运行机制与开发流程,为深入学习模块化编程打下基础。模块化(Modularization)

weixin_29717341的博客 1042

OSGi框架

3.Hello World两个工程        Zzhello:public interface Hello { public void syaHello(); }public class HelloImpl implements Hello{ final String helloString; public HelloImpl(String helloString) { this...

Thankdj 1万+

全面掌握OSGi:入门、进阶到实战指南

本文还有配套的精品资源,点击获取 简介:OSGi是一种模块化和可管理的Java应用程序标准,通过动态管理和版本控制提升应用灵活性和可维护性。本课程分为入门篇、进阶篇和实战篇,内容涵盖了OSGi的核心概念和高级应用,如模块系统、生命周期管理、服务注册与查找、动态部署、依赖注入、安全机制等。此外,还包括了如何构建OSGi应用、与Spring集成、Eclipse RCP开发、企业...

weixin_29155599的博客 2061

OSGi入门与Web应用部署指南

本文还有配套的精品资源,点击获取 简介:OSGi 是一种模块化系统和Java服务框架,其核心是模块化和组件化的设计思想,支持创建、部署和管理可互操作的Java模块。本指南为初学者提供OSGi基础概念的理解,演示如何与Spring框架集成及构建Web应用。内容涵盖模块(Bundle)生命周期管理、服务注册与发现、与Spring的集成、Web应用配置和示例实践。另外,本指南还提...

weixin_42602368的博客 1220

实例讲解OSGI开发

<br /> OSGI,或者通俗点说JAVA动态模块系统,定义了一套模块应用开发的框架。OSGI容器实现方案如Knopflerfish, Equinox, and Apache Felix允许你把你的应用分成多个功能模块,这样通过依赖管理这些功能会更加方便。<br />和Servlet和EJB规范类似,OSGI规范包含两大块:一个OSGI容器需要实现的服务集合;一种OSGI容器和应用之间通信的机制。开发OSGI平台意味着你需要使用OSGI API编写你的应用,然后将其部署到OSGI容器中。从开发者的视角来看

Laurence 6624

四大OSGI框架最新技术对比分析

四大OSGI框架Felix, Eqinox, Spring-DM, Knopflerfish最新技术对比分析

OSGi深入讲解(一)

OSGi是一种Java动态模块化系统标准,通过Bundle(模块)实现应用的拆分与隔离。其核心包括类加载隔离、服务通信机制和独立生命周期管理。OSGi支持热部署和动态扩展,适合企业应用、IDE和物联网平台开发。架构包含Bundle、服务、生命周期等多层,采用特殊的类加载机制实现包隔离。开发中需注意接口与实现分离、精确声明依赖等问题。主流实现有Equinox和Felix,可与Spring等框架集成。OSGi解决了传统Java模块化的局限,支持动态服务发现和版本管理,是构建可扩展系统的理想选择。

onlymscn的博客 769

CS224W图神经网络实战:如何用Motifs和Graphlets分析社交网络结构?

本文基于斯坦福CS224W课程,深入探讨了如何利用网络模体(Motifs)和图元(Graphlets)分析社交网络的微观结构。通过实战代码演示,文章介绍了如何识别具有统计显著性的关键连接模式,计算节点的图元度向量以刻画局部拓扑特征,并将这些结构洞见应用于社区发现、影响力分析及图神经网络的节点特征工程,从而提升模型在虚假账号检测等任务中的性能。

2w3e4r5t6y的博客 910

新手如何结合pbootCMS和宝塔面板快速构建网站

摘要: 新手可通过pbootCMS(轻量CMS)和宝塔面板(可视化工具)快速搭建网站,无需命令行。步骤包括:1) 准备服务器(Linux/CentOS7.x)和域名;2) 安装宝塔面板并配置LNMP环境(PHP7.4+MySQL5.7);3) 创建网站目录,上传并解压pbootCMS源码,设置文件权限;4) 运行安装向导,填写数据库信息和管理员账号;5) 测试前台/后台功能,优化性能并绑定域名。全程约30-60分钟,宝塔简化运维,pbootCMS便于内容管理,适合零基础用户。注意定期更新和备份以保障安全。

qinzhenyan的博客 1639

实例讲解OSGI入门开发

/** *  转载请注明作者longdick    http://longdick.iteye.com * */     OSGI(Open Services Gateway Initiative),或者通俗点说JAVA动态模块系统,定义了一套模块应用开发的框架。OSGI容器实现方案如Knopflerfish, Equinox, and Apache Fel

txp1993的专栏 669

Meta DINOv3实战指南:如何用7B参数ViT模型搞定图像分割与检测(附Hugging Face配置)

本文提供了Meta DINOv3模型的实战应用指南,重点介绍了如何利用这个7B参数的视觉Transformer模型进行图像分割与目标检测。通过详细的Hugging Face配置步骤、环境搭建、模型加载与推理优化,帮助开发者快速上手这一强大的自监督视觉模型,并高效应用于实际计算机视觉任务中。

s3t4u的博客 903

自己的osgi收藏(比较详尽的osgi学习文档)四spring-osgi集成

 2.与流行的 JAVA B/S体系架构的集成  了解了基于osgi系统设计的基本思想,进一步来研究osgi与流行的框架(spring,struts,hibernate等)的集成,这里首先讲解一下集成原理。l        解决和spring的集成  由于spring的应用占据了大部分的java应用领域,所以解决与spring的集成是osgi必须解决的,spring-dm的推出大大

光辉的技术收藏 8959

旅行青蛙破解汉化教程——蹭个热度

汉化破解版资源(无尽三叶草与点券): https://github.com/wisdombyzf/lxqw/blob/master/lxqw_zf.apk 截图: 破解方法: 工具: 1,APKIDE https://www.pd521.com/thread-818-1-2.html 2,dnspy https://down.52pojie.

github_38838414的博客 3783

保姆级教程:在LKD3588开发板上为RK3588添加SC2210摄像头驱动(含完整DTS配置)

本文提供了一份详细的教程,指导如何在LKD3588开发板上为RK3588处理器添加SC2210摄像头驱动,包括完整的DTS配置和内核编译步骤。教程涵盖了环境准备、驱动文件添加、DTS配置详解、内核编译与烧录、驱动测试以及常见问题排查,帮助开发者快速实现SC2210传感器在RK3588平台上的集成与优化。

weixin_42641741的博客 479

OSGi深入讲解(二)

摘要:本文深入探讨OSGi框架中的Declarative Services(DS)和Blueprint两种服务开发方式,分析其核心功能与使用场景。DS通过注解简化服务注册和管理,Blueprint采用类似Spring的XML配置风格。文章详细介绍了OSGi开发流程、性能优化、调试技巧,并结合Eclipse插件、物联网网关等实际案例,阐述OSGi在动态扩展、热部署等方面的优势。最后总结了最佳实践,包括接口分离、声明式服务、动态资源管理等,为构建可扩展的企业级应用提供指导。

onlymscn的博客 824

大模型角色提示词写得再严密,也能被绕过?我用攻击者思维把自己吓了一跳!

很多人以为提示词是“只要写清楚了,模型就能理解”,但实际上——模型并不具备严格的规则意识,它只是在预测下一句话。所以我们必须从“攻防”角度出发,设计更强的防护机制。我这次就是亲身踩坑,用红队思维模拟攻击,才意识到原来提示词注入这么容易中招。你如果也在做 AI 应用、角色系统、提示词驱动的功能,建议你也用类似方式测试一下,不然被绕了都不知道。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1026

osgi实例讲解

OSGI(Open Services Gateway Initiative),或者通俗点说JAVA动态模块系统,定义了一套模块应用开发的框架。OSGI容器实现方案如Knopflerfish, Equinox, and Apache Felix允许你把你的应用分成多个功能模块,这样通过依赖管理这些功能会更加方便。 和Servlet和EJB规范类似,OSGI规范包含两大块:一个OSGI容器需要实

hzllblzjily的专栏 511

【YOLOv8/v9/v10 实战 01】YOLOv8/v9/v10全系列实战对决:性能矩阵、架构拆解与2026部署指南

2026年YOLO生态已进入“战国时代”,Ultralytics YOLOv8/11/26、阿里YOLO12、清华YOLOv10、微软YOLOv9四大路线并行发展。本文基于官方文档、学术论文及实测数据,系统剖析三大核心版本(YOLOv8/v9/v10)的架构演进逻辑,构建覆盖参数量、mAP、FPS、FLOPs的完整性能矩阵。通过8组工业场景实测、全流程代码实现(训练-导出-部署)、6类硬件适配方案,解决新手选型难、进阶者优化无门、工业开发者部署低效的痛点。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 533

SQL Server数据库备份与恢复

在 SQL Server 中,数据库备份与恢复是保障数据安全的核心操作。

zjw541806的博客 1876

OSGI项目搭建、运行、与打包实例

一 、新建osgi项目流程 1.在左侧Porject Explorer里右键:new -- other -- plug-in object 如图: Next ----Next --选个Hello Osgi Bundel: Next 这里可以设置项目启动和项目停止时打印的一句话 Finish 项目创建完成! 2.项目运行 右键选择项目---Run As -- Run config里,选择osgi--new--选择项目启动要运行的bundel 要选择的bundel除了本身

青草非鱼 777

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

上一篇: Java中的不可变类
下一篇: 详解ClassLoader加载类的流程及自定义ClassLoader
hxwhou
博客等级 码龄16年 100粉丝 64原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值