1. 程式人生 > >OSGI實戰教程【Spring DM】編寫一個簡單的Bundle元件

OSGI實戰教程【Spring DM】編寫一個簡單的Bundle元件

OSGI實戰教程

關鍵字: Spring DMFelixKarafServiceMixOSGI

本教程使用相關工具:

  • 1、開發工具:Eclipse
  • 2、依賴管理:Maven
  • 3、OSGI容器:ServiceMix

目標:教程演示使用Maven構建,採用Spring DM開發一個最基本的OSGI元件,並將元件運行於ServiceMix容器中。

1、建立專案:

專案結構
建立一個普通的Maven工程,怎麼建立就不累贅了。

2、匯入依賴

<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.micai.test</groupId> <artifactId>osgi-hello-liyong</artifactId> <version
>
0.0.1-SNAPSHOT</version> <packaging>bundle</packaging> <name>osgi-hello-liyong</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version
>
4.3.12.RELEASE</spring.version> <felix.plugin.version>3.2.0</felix.plugin.version> <osgi.version>4.2.0</osgi.version> <spring.osgi.version>1.2.1</spring.osgi.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.osgi</groupId> <artifactId>spring-osgi-core</artifactId> <version>${spring.osgi.version}</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>org.springframework.core</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>org.springframework.aop</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>org.springframework.beans</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>org.springframework.context</artifactId> </exclusion> <exclusion> <groupId>org.aopalliance</groupId> <artifactId>com.springsource.org.aopalliance</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.osgi</groupId> <artifactId>spring-osgi-web</artifactId> <version>${spring.osgi.version}</version> <scope>provided</scope> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>org.springframework.core</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>org.springframework.aop</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>org.springframework.beans</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>org.springframework.context</artifactId> </exclusion> <exclusion> <groupId>javax.servlet</groupId> <artifactId>com.springsource.javax.servlet</artifactId> </exclusion> <exclusion> <groupId>org.aopalliance</groupId> <artifactId>com.springsource.org.aopalliance</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.osgi</groupId> <artifactId>spring-osgi-extender</artifactId> <version>${spring.osgi.version}</version> <scope>provided</scope> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>org.springframework.core</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>org.springframework.aop</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>org.springframework.beans</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>org.springframework.context</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <target>1.6</target> <source>1.6</source> </configuration> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>${felix.plugin.version}</version> <configuration> <instructions> <Import-Package> * </Import-Package> <Karaf-Commands>*</Karaf-Commands> </instructions> </configuration> <extensions>true</extensions> </plugin> </plugins> </build> </project>

依賴引入關鍵點:

  • 2.1、引入maven-bundle-plugin外掛
<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <version>${felix.plugin.version}</version>
    <configuration>
        <instructions>
            <Import-Package>
                *
            </Import-Package>
            <Karaf-Commands>*</Karaf-Commands>
        </instructions>
    </configuration>
    <extensions>true</extensions>
</plugin>

使用這個外掛後,我們就不用再配置OSGI相關的描述檔案了,所有OSGI的屬性該外掛已經在打包的時候為我們新增完成,我們只需要開發自己的業務就行了。

  • 2.2、打包型別
<packaging>bundle</packaging>

這點是與我們正常的的專案不同地方,正常專案我們都是配置pom、jar、war等

說明:如果在你的程式碼中報錯:Project build error: Unknown packaging: bundle,那麼僅需要在plugin中新增 <extensions>true</extensions> 即可

  • 2.3、引入Spring OSGI相關的依賴包,該依賴配置中排除了spring-osgi中低版本的spring相關jar,手動引入了高版本的spring依賴

3、編寫一個簡單的Spring Bean

package com.micai.test.osgi.hello;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.stereotype.Service;

@Service
public class HelloWorldService {
    @PostConstruct
    public void init() {
        System.out.println("Bean初始化");
    }

    @PreDestroy
    public void destroy() {
        System.out.println("Bean銷燬");
    }
}

4、編寫Spring相關配置 spring-context.xml

配置檔名稱沒有特殊要求,但是放置的位置必須在指定位置
這裡寫圖片描述
必須放置於classpath下面的: META-INF/spring目錄中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:osgi="http://www.springframework.org/schema/osgi"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
                        http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd">

    <context:component-scan base-package="com.micai.test.osgi.hello" />

</beans>

該出配置沒有什麼特殊的配置,僅僅配置了包掃描功能。我們的簡單元件就開發完成了。

5、打包

直接通過maven命令

mvn install

進行打包安裝到本地,這裡因為我使用 mvn build打包報錯,用install反而好使了,暫時沒時間糾結為什麼。。。

6、釋出

將打好的jar包上傳到自己準備好的ServiceMix容器環境的釋出目錄:
釋出目錄:在ServiceMix的安裝目錄中的 deploy資料夾中。
這裡寫圖片描述

karaf@root>Bean初始化
karaf@root>bundle:list | grep "osgi-hello-liyong"
265 | Active   |  80 | 0.0.1.SNAPSHOT                     | osgi-hello-liyong
karaf@root>bundle:stop 265
Bean銷燬
karaf@root>bundle:start 265
karaf@root>Bean初始化

當上傳成功後,元件就自動重啟了,即spring容器也初始化了,由於我們直接使用列印命令列印內容到控制檯了,那麼在我們的ServiceMix的控制檯上面就可以看到Bean初始化時列印的訊息。
當我們使用相關命令停止該bundle時,spring容器被銷燬了,bean也就銷燬了,所以執行了我們bean配置中的銷燬方法。