OSGi容器中Bundle之间Synchronous Communication

    OSGi Core定义了一个服务层,提供了一个Bundle之间交互的简单机制,通过注册Java Object 至OSGi service registry。     Blueprint Container

    (1) Blueprint Configuration

    默认配置文件位于:ProjectDir/src/main/resources/OSGI-INF/blueprint

    默认XML文件命名空间:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
	...
</blueprint>

    自定义配置文件地址:

     Bundle-Blueprint: lib/account.xml, security.bp, cnf/*.xml

     Mandatory dependencies:

     OSGi Service 中Dependencies默认是必须的,但可通过设置reference和reference-list元素的availability为optional

     来改变这中现象。正常情况下,当Bluepring Container初始化时,通过一定范围的时间来允许Dependencies

     Resolve, 该时间么哦人为:5秒,可通过下面的方式自定义:

Bundle-SymbolicName: org.fusesource.example.osgi-client;
blueprint.graceperiod:=true;
blueprint.timeout:= 10000

    (2) Defining a Service Bean

    (3) Exporting a Service

    1. Exporting with a single interface

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
	<bean id="savings" class="org.fusesource.example.SavingsAccountImpl" />
	<service ref="savings" interface="org.fusesource.example.Account" />
</blueprint>

    2. Exporting with multiple interfaces

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
	
	<bean id="savings" class="org.fusesource.example.SavingsAccountImpl" />
	<service ref="savings">
		<interfaces>
			<value>org.fusesource.example.Account</value>
			<value>org.fusesource.example.SavingsAccount</value>
		</interfaces>
	</service>
</blueprint>

    注意:interface和interfaces不能同时在service元素中使用。

    3. Exporting with auto-export

    例如:下面的代码中Blueprint将自动注册所有SavingsAccountImpl实现的public接口:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
	<bean id="savings" class="org.fusesource.example.SavingsAccountImpl" />
	<service ref="savings" auto-export="interfaces" />
</blueprint>

     其中auto-export默认值为:disabled,其他可选值为:

     interfaces:注册该类实现的所有public的接口;

     class-hierarchy:注册该类自己以及他的父类,但不包含Object类;

     all-classes:注册该类自己以及他的父类,同时包括该类实现的接口。

     4. Setting service properties

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
	<bean id="savings" class="org.fusesource.example.SavingsAccountImpl" />
	<service ref="savings" auto-export="interfaces" ranking="10">
		<service-properties>
			<beans:entry key="bank.name" value="HighStreetBank" />
		</service-properties>
	</service>
</blueprint>

    说明:A.  注册的service默认的Properties有:osgi.service.blueprint.compname值为service  bean 的id

                B.  service.ranking 是系统自动设置。

                C.  当系统查找服务时返回对个匹配的服务时,默认选择ranking值最高的服务,因此可配置该属性用以服务

     之间的区分。

     5. Specifying a registration listener

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" .>
	<bean id="listenerBean" class="org.fusesource.example.Listener" />
	<service ref="savings" auto-export="interfaces">
		<registration-listener ref="listenerBean"
			registration-method="register" unregistration-method="unregister" />
	</service>
</blueprint>
//Java
package org.fusesource.example;

public class Listener {
	public void register(Account service, java.util.Map serviceProperties) {
	}

	public void unregister(Account service, java.util.Map serviceProperties) {
	}
}

     说明:register和unregister方法的参数,第一个参数可以是service class或service class 实现的接口,因为该

     参数包含service instance,  如果该service bean 被声明为property, 在注册的时候是没有service instance可用

     的,因此此时该参数的值为null.

     第二个参数可以是java.util.Map或java.util.Dictionary,这个Map包含service 注册时的Properties.

     (4) Importing a Service

     使用reference和reference-list元素Import Service, 两者之间的区别是:reference用于访问stateless service,

     而reference-list用于访问stateful service.

     1. Matching by interface (stateless)

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
	<reference id="savingsRef" interface="org.fusesource.example.SavingsAccount" />
	<bean id="client" class="org.fusesource.example.client.Client">
		<property name="savingsAccount" ref="savingsRef" />
	</bean>
</blueprint>
package org.fusesource.example.client;

import org.fusesource.example.SavingsAccount;

public class Client {
	SavingsAccount savingsAccount;

	// Bean properties
	public SavingsAccount getSavingsAccount() {
		return savingsAccount;
	}

	public void setSavingsAccount(SavingsAccount savingsAccount) {
		this.savingsAccount = savingsAccount;
	}
}

     2.  Matching by interface (stateful)    

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
	<reference-list id="savingsListRef"
		interface="org.fusesource.example.SavingsAccount" />
	<bean id="client" class="org.fusesource.example.client.Client">
		<property name="savingsAccountList" ref="savingsListRef" />
	</bean>
</blueprint>
package org.fusesource.example.client;

import org.fusesource.example.SavingsAccount;

public class Client {
	java.util.List<SavingsAccount> accountList;

	// Bean properties
	public java.util.List<SavingsAccount> getSavingsAccountList() {
		return accountList;
	}

	public void setSavingsAccountList(java.util.List<SavingsAccount> accountList) {
		this.accountList = accountList;
	}
}

     3. Matching service properties with a filter

<reference id="savingsRef" interface="org.fusesource.example.SavingsAccount" filter="(bank.name=HighStreetBank)" />

<reference-list id="savingsRef" interface="org.fusesource.example.SavingsAccount" filter="(bank.name=HighStreetBank)" />

    4. Specifying whether mandatory or optional

     默认值:mandatory

<reference id="savingsRef" interface="org.fusesource.example.SavingsAccount" availability="mandatory" />

     5. Specifying a reference listener

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
	<reference id="savingsRef" interface="org.fusesource.example.SavingsAccount">
		<reference-listener bind-method="onBind"
			unbind-meth od="onUnbind">
			<bean class="org.fusesource.example.client.Listener" />
		</reference-listener>
	</reference>
	<bean id="client" class="org.fusesource.example.client.Client">
		<property name="savingsAcc" ref="savingsRef" />
	</bean>
</blueprint>
package org.fusesource.example.client;

import org.osgi.framework.ServiceReference;

public class Listener {
	public void onBind(ServiceReference ref) {
		System.out.println("Bound service: " + ref);
	}

	public void onUnbind(ServiceReference ref) {
		System.out.println("Unbound service: " + ref);
	}
}

相关推荐