iPOJO Hello World

简单的样例
下面的简单样例将演示如何使用核心iPOJO概念。样例由2个组件组成。一个提供了Hello服务而另一个使用多个hello服务。这些组件使用Maven被打包成3个不同的bundle。hello.service服务包包含了服务的接口(接口和实现分离)。hello.impl服务包包含了一个实现服务的组件。hello.client服务包包含服务消费组件。

准备Maven 安装示例
第一步,下载并安装Maven;本例子使用Maven 2.2.0来创建。当你机器上安装了Maven后,你就可以编译本例子解压后的项目了,并在项目的根目录下用命令"mvn clean install"

注意:当Maven执行时会输出一些信息,并会经常下载一些需要的JAR文件到本地库中

Hello Service
第一个项目是hello.service,项目仅包含了一个服务接口。
$ mvn archetype:create -DgroupId=iPOJOTutorial -DartifactId=hello.service -Dversion=1.0.0 -DpackageName=ipojo.example.hello

使用mvn创建hello.service项目.
创建src/main/java/ipojo/example/hello/Hello.java
package ipojo.example.hello;
/**
* Hello Interface.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public interface Hello {

/**
* Returns a message like: "Hello $user_name".
* @param name the name
* @return the hello message
*/
String sayHello(String name);
}


在生成的pom.xml文件中修改和添加如下内容:
<packaging>bundle</packaging>

<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>1.4.3</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>
${pom.artifactId}
</Bundle-SymbolicName>
<Export-Package>
ipojo.example.hello
</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>

进入hello.service根目录,输入命令:
mvn clean install


Maven报告构建成功,在根目录下的target目录下你就可以看到生成的bundle了。可以查看该jar文件中的META-INF下的MANIFEST.MF文件中是否有Export-Package、Bundle-*等关键词,如果有说明我们构建输出的是bundle。当然install命令也将我们的bundle发布到本地库中了。本地库方面的知识,读者可自行阅读Maven方面的书籍。


Hello 服务供应者
服务的实现组件是一个普通的实现了Hello Service接口的类。服务组件的实现包含在hello.impl项目中。首先我们还是使用mvn来帮助我们构建项目的骨架。


输入:mvn archetype:create -DgroupId=iPOJOTutorial -Dar
tifactId=hello.impl -Dversion=1.0.0 -DpackageName=ipojo.example.hello.impl。

服务实现如下:
package ipojo.example.hello.impl;
/**
* Component implementing the Hello service.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
import ipojo.example.hello.Hello;
public class HelloImpl implements Hello {

/**
* Returns an 'Hello' message.
* @param name : name
* @return Hello message
* @see ipojo.example.hello.Hello#sayHello(java.lang.String)
*/
public String sayHello(String name) { return "hello " + name; }
}

为了管理组件,iPOJO还需要metadata来描述组件提供的Hello服务。iPOJO metadata文件在hello.impl项目的根目录下,名字为metadata.xml。它包含了一下元数据(iPOJO也支持JAR的mainifest风格的语法)

<iPOJO>
<component className="ipojo.example.hello.impl.HelloImpl" name="HelloProvider">
<provides />
</component>
<instance component="HelloProvider" name="HelloService" />
</iPOJO>


pom.xml文件内容如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>iPOJOTutorial</groupId>
<artifactId>hello.impl</artifactId>
<packaging>bundle</packaging>
<version>1.0.0</version>
<name>hello.impl</name>
<url>http://maven.apache.org</url>
<dependencies>

<dependency> <!--Compilation (i.e. class) dependency on the service interface -->
<groupId>iPOJOTutorial</groupId>
<artifactId>hello.service</artifactId>
<version>1.0.0</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>1.4.3</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
<Private-Package>ipojo.example.hello.impl</Private-Package>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-ipojo-plugin</artifactId>
<version>1.2.0</version>
<executions>
<execution>
<goals>
<goal>ipojo-bundle</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</dependencies>

</project>

本项目首先依赖接口,所以比上一个项目增加了一个<dependency>。同时还增加了一个maven-ipojo-plugin。

当上面的工作完成并进入项目的根目录后,我们就可以使用mvn clean install来构建项目了。

成功构建bundle后,在bundle中的MANIFEST.MF内容如下:
Manifest-Version: 1.0
Private-Package: ipojo.example.hello.impl
iPOJO-Components: component { $name="HelloProvider" $classname="ipojo.
example.hello.impl.HelloImpl" $architecture="true" provides { }manipu
lation { method { $name="$init" }method { $arguments="{java.lang.Stri
ng}" $name="sayHello" $return="java.lang.String" }interface { $name="
ipojo.example.hello.Hello" }}}instance { $component="HelloProvider" $
name="HelloService" }
Built-By: zhangcm
Tool: Bnd-0.0.255
Bundle-Name: hello.impl
Created-By: Apache Maven Bundle Plugin & iPOJO
Bundle-Version: 1.0.0
Build-Jdk: 1.6.0_06
Bnd-LastModified: 1247623899280
Bundle-ManifestVersion: 2
Import-Package: org.osgi.service.log;version=1.3, org.apache.felix.ipo
jo.architecture;version= 1.2.0, ipojo.example.hello, org.apache.felix
.ipojo;version= 1.2.0, org.osgi.service.cm;version=1.2
Bundle-SymbolicName: hello.impl


Hello Service 客户端
Hello服务消费在项目hello.client中。使用mvn创建该项目:

mvn archetype:create -DgroupId=iPOJOTutorial -DartifactId=hello.client -Dversion=1.0.0 -DpackageName=ipojo.example.hello.client。
客户端代码如下:

package ipojo.example.hello.client;

import ipojo.example.hello.Hello;

/**
* Hello Service simple client.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class HelloClient implements Runnable {

/**
* Delay between two invocations.
*/
private static final int DELAY = 10000;

/**
* Hello services.
* Injected by the container.
* */
private Hello[] m_hello; // Service Requirement

/**
* End flag.
* */
private boolean m_end;

/**
* Name property.
* Injected by the container.
* */
private String m_name;

/**
* Run method.
* @see java.lang.Runnable#run()
*/
public void run() {
while (!m_end) {
try {
invokeHelloServices();
Thread.sleep(DELAY);
} catch (InterruptedException ie) {
/* will recheck end */
}
}
}

/**
* Invoke hello services.
*/
public void invokeHelloServices() {
for (int i = 0; i < m_hello.length; i++) {
System.out.println(m_hello[i].sayHello(m_name));
}
}

/**
* Starting.
*/
public void starting() {
Thread thread = new Thread(this);
m_end = false;
thread.start();
}

/**
* Stopping.
*/
public void stopping() {
m_end = true;
}
}


Hello Service 客户端创建一个线程,间断性地调用Hello服务。当至少存在一个hello服务的供应者,iPOJO回调机制
会调用客户端的starting方法来启动线程。在客户端代码中,为了使用hello服务的实现组件,只需要简单地定义服务接口类型的字段。在本项目中,那它就是m_hello。请注意m_hello字段是一个Hello数组。在iPOJO中服务数组表示聚合依赖。whereas if a scalar value represents a singular or unary cardinality dependency. In other words, for a singular dependency simply remove the array brackets from the example (e.g., HelloService m_hello[]. After declaring a field for the service, the rest of the component code can simply assume that the service field will be initialized, e.g., m_hello[i].sayHello("world").

注意:iPOJO也管理服务的同步。因此,服务的调用时不需要同步块(synchronization)。这种同步是基于每线程基础上的。每一种方法访问的服务是附加在线程上的给定的服务实例,因此线程将会一直能看到同一个服务实例,甚至跨入嵌套方法调用。线程除了完全从第一个它进入的服务方法中退出为至。。因此,你不需要在run()方法之外存取服务,因为线程将永远看到相同的服务实例。

本组件提供了2个回调方法starting() stopping()分别用于激活和去激活。当组件需要得到有关组件状态改变的通知,就需要用到回调了。在iPOJO中,组件只有2个状态INVALID(组件的约束不满足,如依赖的服务不存在)和VALID(组件的约束满足)。在本例中,starting 回调方法创建并开启线程。stopping回调方法停止线程。组件元数据指示iPOJO调用这两个方法,当组件状态在VALID或者INVALID变化时。


在本项目的根目录下,创建metadata.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<iPOJO>
<component className="ipojo.example.hello.client.HelloClient"
architecture="true">
<requires field="m_hello" />
<callback transition="validate" method="starting" />
<callback transition="invalidate" method="stopping" />
<properties>
<property field="m_name" name="hello.name" />
</properties>
</component>
<instance component="ipojo.example.hello.client.HelloClient">
<property name="hello.name" value="clement" />
</instance>
</iPOJO>

pom.xml文件内容如下:
<project>
<modelVersion>4.0.0</modelVersion>
<packaging>bundle</packaging>
<groupId>iPOJOTutorial</groupId>
<artifactId>hello.client</artifactId>
<version>1.0.0</version>
<name>Hello Client</name>

<dependencies>
<dependency> <!-- Compilation (i.e. class) dependency on the service interface -->
<groupId>iPOJOTutorial</groupId>
<artifactId>hello.service</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>1.4.3</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
<Private-Package>ipojo.example.hello.client</Private-Package>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-ipojo-plugin</artifactId>
<version>1.2.0</version>
<executions>
<execution>
<goals>
<goal>ipojo-bundle</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

构建客户端:mvn clean install




示例运行:
启动Felix运行本示例。
java -jar bin/felix.jar
Welcome to Felix.
=================

-> ps
START LEVEL 1
ID State Level Name
[ 0] [Active ] [ 0] System Bundle (1.4.1)
[ 1] [Active ] [ 1] Apache Felix Shell Service (1.0.2)
[ 2] [Active ] [ 1] Apache Felix Shell TUI (1.0.2)
[ 3] [Active ] [ 1] Apache Felix Bundle Repository (1.2.1)
[ 4] [Active ] [ 1] Apache Felix iPOJO (1.2.0)
[ 5] [Active ] [ 1] Apache Felix iPOJO Arch Command (1.2.0)
->


start file:../hello.service/target/hello.service-1.0.0.jar
start file:../hello.impl/target/hello.impl-1.0.0.jar
start file:../hello.client/target/hello.client-1.0.0.jar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值