OSGI框架下,bundle的两种启动方式

来源:互联网 发布:网络真人赌博软件开发 编辑:程序博客网 时间:2024/05/16 05:26

什么是Bundle?

如果有人问你,什么是osgi?其最大特点是什么?你只要回到"模块化开发体系",足矣。要是你能说出来java9的模块化开发体系并与之对比,那就说明你是专业的。

既然是模块化开发体系。那么osgi中的模块就是bundle,bundle是osgi中的最基本单位。

osgi中的bundle是jar文件格式规范基础上扩展出来的,一个符合osgi规范的bundle首先必须是一个符合jar文件格式规范的jar包。bundle相对普通的jar包做了以下

三方面扩展:

1)jar文件格式规范里定义的/META-INF/MANIFEST.MF文件用于描述jar包的元数据信息,如jar包的版本,数字签名信息等。bundle的MANIFEST.MF对其添加了大

量的扩展定义。如描述该bundle可以提供哪些资源、依赖哪些其他bundle、启动或卸载时要执行哪些动作等。

2)加入了一个可选的/OSGI-OPT文件夹,可以在其中保存一些与Bundle运行无关的信息,比如bundle源码、软件说明书等。

3)Bundle中可以包含一些具备特殊含义的程序和资源,如使用Bundle-Activator定义的初始化类、定义在OSGI-INF/110n目录下的本地化信息等。

bundle的生命周期?

UNINSTALLED、INSTALLED、RESOLVED、STARTING、STOPPING、ACTIVE

bundle如何启动?

1)实现BundleActivator接口。此接口只有两个方法

  public void start(BundleContext context) throws Exception; 除了可以启动此bundle以外还可以用来这种方法可以用来注册服务或分配这个bundle需要的任何资源。

调用此方法时bundle的状态为STARTING。正确执行完此方法后bundle状态为ACTIVE。

  public void stop(BundleContext context) throws Exception;除了可以卸载bundle以外还可以用此方法释放资源,注销服务等。调用此方法时Bundle的状态为

STOPPING,正确执行完此方法后Bundle状态为RESOLVED。

2)通过blueprint启动bundle。

创建一个blueprint的xml文件。例如:bundle-name-impl/src/main/resources/org/opendaylight/blueprint/bundle-name-blueprint.xml

还可以在其中启动自定义COMMAND。也可以起初始化bundle初始化类。

例如:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
    odl:restart-dependents-on-updates="true" odl:use-default-for-reference-types="true">
     <!-- reference to MD-SAL service -->//获取初始化本bundle所需的服务。
    <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" odl:type="default" />
    <reference id="notificationService" interface="org.opendaylight.controller.md.sal.binding.api.NotificationService" odl:type="default"/>
    <reference id="notificationPublishService" interface="org.opendaylight.controller.md.sal.binding.api.NotificationPublishService" odl:type="default"/>
    <reference id="rpcProviderRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry" odl:type="default"/>
  
    <!-- init ExampleInitializer and inject its dependencies -->//为此bundle初始化传入参数。可以是服务信息,也可以是其他信息例如:name->zjc
    <bean id="initiater" class=com.stackpush.csdn.www.ExampleInitializer"
          init-method="init" destroy-method="close">
        <argument ref="dataBroker"/>
        <argument ref="notificationService"/>
        <argument ref="notificationPublishService"/>
        <argument ref="rpcProviderRegistry"/>
        <property name="name" value="csdn_stackpush"/>
    </bean>


    <!-- register service 1, service 2-->
    <bean id="service1" class="com.stackpush.csdn.www.Service1">
        <argument value="INSTANCE"/>
    </bean>
    <bean id="service2" class="com.stackpush.csdn.www.Service2">
        <argument value="INSTANCE"/>
    </bean>
    <service ref="service1" interface="com.stackpush.csdn.www.Service1"/>
    <service ref="service2" interface="com.stackpush.csdn.www.Service1"/>
  
    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.0.0">
        <command name="cmd-cmd/help">
            <action class="com.stackpush.csdn.www.command.Help"/>
        </command>
    </command-bundle>
</blueprint>

对应的初始化类为:

public class ExampleInitializer implements AutoCloseable {
    private final DataBroker dataBroker;
    private final NotificationService notificationService;
    private final NotificationPublishService notificationPublishService;
    private final RpcProviderRegistry rpcProviderRegistry;
    private String name;


    public ExampleInitializer(DataBroker dataBroker, NotificationService notificationService,
            NotificationPublishService notificationPublishService, RpcProviderRegistry rpcProviderRegistry) {
        this.dataBroker = dataBroker;
        this.notificationPublishService = notificationPublishService;
        this.notificationService = notificationService;
        this.rpcProviderRegistry = rpcProviderRegistry;
        System.out.println("hello, I began to work. my name is:" + name);
    }


    public void init() {
     MyDataBroker.setDataBroker(dataBroker);
    }
    @Override
    public void close() throws Exception {
    }
}

对应的COMMAND类为:

@Command(scope = "cmd-cmd", name = "help", description = " help")
public class Help extends OsgiCommandSupport {


    @Override
    protected Object doExecute() throws Exception {
        System.out.println("      cmd-cmd:help         help help");
    }
}

要想让COMMAMD运行起来需要依赖:

        <dependency>
            <groupId>org.apache.karaf.shell</groupId>
            <artifactId>org.apache.karaf.shell.console</artifactId>
        </dependency>

如果需要TABLE显示需要依赖:
        <dependency>
            <groupId>org.apache.karaf.shell</groupId>
            <artifactId>org.apache.karaf.shell.table</artifactId>
        </dependency>

原创粉丝点击