Importpackage/Export package
在OSGI里,bundle暴露自己的类(Export)或引用其他bundle的类(Import)的单位是package(就是每个java代码文件最上头定义的Package),也就是对于bundle来说,只能将整个package里的类暴露或引用进来,而不是对单个类作暴露或引用,所以,我们在设计时,应考虑将需暴露出去的类放在一个或几个package里,而将需隐藏起来的类放在其他的package里。
OSGIService
OSGIframework提供了一个osgiservice registry,我们可以将一个javabean注册到这个osgiservice registry上,然后,其它的bundle就可以通过osgiservice registry来发现和引用这个Javabean,而这个Javabean就是一个OSGIService(OSGI服务)了。
java代码注册和引用
服务注册到osgi环境中去,当前osgi环境的所有的bundle可以通过bundlecontxt获取服务
注册服务
1.packagecom.ponder.Demo.demo2;
import com.ponder.Demo.demo2.Impl.Calculation;
import com.ponder.Demo.demo2.contract.ICalculation;
import java.util.HashMap;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
/**
*
* @author han
*/
public class activator implements BundleActivator {
@Override
public void start(BundleContext context) throws Exception {
Dictionary<String, String> props = new Hashtable<String, String>();
props.put("ServiceName", "Calculation");//
服务属性
(
服务名称为”
Calculation”)
//
注册服务
context.registerService(ICalculation.class.getName(), new Calculation(), props);
System.out.println("Service registered!");
}
@Override
public void stop(BundleContext context) throws Exception {
System.out.println("Stop demo2 bundle!");
}
}
2.pom.xml中exportpackage
<manifestEntries>
<Export-Package>com.ponder.Demo.demo2.contract;version="1.0"</Export-Package>
</manifestEntries>
引用服务
1.我们先看看demo3activator的start方法:
@Override
public void start(BundleContext context) throws Exception {
ServiceReference[] refs = context.getServiceReferences(ICalculation.class.getName(), "(ServiceName=Calculation)");
if(refs!=null && refs.length>0){
ICalculation service=(ICalculation)context.getService(refs[0]);
System.out.println("1+1="+service.add(1, 1));
System.out.println("2-1="+service.sub(2, 1));
System.out.println("2*3="+service.sub(2, 3));
}
}
2.pom.xml中importpackage
<Import-Package>org.osgi.framework,com.ponder.Demo.demo2.contract;version="[1.0,2.0)"</Import-Package>
</manifestEntries>
BundleActivator
1.pom.xml
<Bundle-Activator>com.dtdream.csr.oss.manager.ManagerActivator</Bundle-Activator>
bundlestart后会调用ManagerActivator
publicclass ManagerActivator implements BundleActivator {
@Inject
BundleContextcontext;
}
ServiceTracker
public class TransmitterTracker extends ServiceTracker<Transmitter, Transmitter> {
public TransmitterTracker(BundleContext context) {
super(context, Transmitter.class, null);
}
@Override
public Transmitter addingService(ServiceReference<Transmitter> reference) {
}
@Override
public void removedService(ServiceReference<Transmitter> reference,
super.removedService(reference, transmitter);
}
}
Blueprint
OSGI服务的注册
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"
>
<!--
实例化
-->
<bean id="Calculation" class="com.ponder.Demo.demo6.Impl.Calculation"/>
<!--
发布成
OSGI
服务
-->
<service id="CalculationService" ref="Calculation" interface="com.ponder.Demo.demo2.contract.ICalculation">
<service-properties>
<entry key="ServiceName" value="Calculation"/>
</service-properties>
</service>
</blueprint>
OSGI
服务的引用
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<!--
引用服务
-->
<reference id="calculationservice" interface="com.ponder.Demo.demo2.contract.ICalculation" filter="(ServiceName=Calculation)"/>
<!--
实例化
-->
<bean id="MyBean" class="com.ponder.Demo.demo7.Impl.DIWithBlueprint">
<!--
注入服务引用
-->
<property name="calculator" ref="calculationservice"/>
</bean>
</blueprint>
注意:reference
包含了id、interface和filter三个属性。其中,interface指定了要引用的OSGI服务的接口,这个接口必须是可见的,这里是通过Import-Package从demo2-1这个bundle那里引入的。interface属性是必须指定的。filter则是一个过滤条件,它是根据OSGI服务的服务属性来过滤的,这个属性是可选的。如果同一接口注册了多个OSGI服务的话,reference会随机地绑定其中一个,所以如果你需要明确指定其中某一个实例的话,则需要通过服务属性来界定。
2.我们定义了一个类com.ponder.Demo.demo7.Impl.DIWithBlueprint,这个类里有一个setter方法setCalculator(ICalculationservice):
package
com.ponder.Demo.demo7.Impl;
import
com.ponder.Demo.demo2.contract.ICalculation;
/**
*
* @author han
*/
public
class
DIWithBlueprint
{
private
ICalculation calculator;
public
void
setCalculator
(ICalculation service)
{
this
.calculator = service;
System.out.println();
System.out.println(
"7+1="
+ calculator.add(
7
,
1
));
System.out.println(
"7-1="
+ calculator.sub(
7
,
1
));
System.out.println(
"7*3="
+ calculator.mul(
7
,
3
));
}
}