精华内容
下载资源
问答
  • 基于Android平台的OSGi架构中间件的研究与应用.pdf
  • osgi架构与linux 在构建可扩展,可靠的分布式系统的背景下,“模块化”和“微服务体系结构”这两个术语如今经常出现。 众所周知,Java平台本身在模块化方面很弱( Java 9将通过交付Jigsaw项目来解决此问题),这为...

    osgi架构与linux

    在构建可扩展,可靠的分布式系统的背景下,“模块化”和“微服务体系结构”这两个术语如今经常出现。 众所周知,Java平台本身在模块化方面很弱( Java 9将通过交付Jigsaw项目来解决此问题),这为OSGiJBoss Modules等框架的出现提供了机会。

    当我在2007年第一次听说OSGi时 ,我真的很高兴Java应用程序可以在其之上构建而受益。 但是很快就产生了挫败感,而不是兴奋感:没有工具支持,兼容的库和框架非常有限,非常不稳定,难以对运行时进行故障排除。 显然,普通的Java开发人员还没有准备好使用它,因此,我不得不把它放在架子上。 多年来, OSGi已经成熟很多,并得到了广泛的社区支持。

    好奇的读者可能会问:特别是使用模块和OSGi有什么好处? 仅举几个问题,它有助于解决:

    • 显式(和版本控制)依赖关系管理:模块声明所需的内容(以及可选的版本范围)
    • 占用空间小:模块未包装所有依赖项
    • 易于发布:模块可以独立开发和发布
    • 热部署:可以在不影响其他模块的情况下重新部署各个模块

    在今天的帖子中,我们将对使用OSGi构建模块化Java应用程序的最新技术水平进行10000英尺的考察。 撇开OSGi的好坏进行讨论,我们将构建一个包含以下模块的示例应用程序:

    • 数据访问模块
    • 商业服务模块
    • REST服务模块

    用于数据访问的Apache OpenJPA 2.3.0 / JPA 2.0 (不幸的是,我们选择的OSGi实现尚未支持JPA 2.1 ),用于REST层的Apache CXF 3.0.1 / JAX-RS 2.0是应用程序的两个主要构建块。 我发现Christian Schneider的博客Liquid Reality是有关OSGi (以及许多其他主题)的宝贵信息来源。

    OSGi世界中,这些模块称为bundles 。 捆绑包显示了它们的依赖关系(导入包)和它们公开的包(导出包),因此其他捆绑包可以使用它们。 Apache Maven也支持此打包模型。 捆绑包由OSGi运行时或容器管理,在我们的情况下将是Apache Karaf 3.0.1 (实际上,这是我们需要下载 和解压缩的内容)。

    让我停止说话,更好地显示一些代码。 我们将从顶部( REST )开始,一直到底部(数据访问),因为它更容易遵循。 我们的PeopleRestServiceJAX-RS 2.0服务实现的典型示例:

    package com.example.jaxrs;
    
    import java.util.Collection;
    
    import javax.ws.rs.DELETE;
    import javax.ws.rs.DefaultValue;
    import javax.ws.rs.FormParam;
    import javax.ws.rs.GET;
    import javax.ws.rs.POST;
    import javax.ws.rs.PUT;
    import javax.ws.rs.Path;
    import javax.ws.rs.PathParam;
    import javax.ws.rs.Produces;
    import javax.ws.rs.QueryParam;
    import javax.ws.rs.core.Context;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.Response;
    import javax.ws.rs.core.UriInfo;
    
    import com.example.data.model.Person;
    import com.example.services.PeopleService;
    
    @Path( "/people" )
    public class PeopleRestService {
        private PeopleService peopleService;
            
        @Produces( { MediaType.APPLICATION_JSON } )
        @GET
        public Collection< Person > getPeople( 
                @QueryParam( "page") @DefaultValue( "1" ) final int page ) {
            return peopleService.getPeople( page, 5 );
        }
    
        @Produces( { MediaType.APPLICATION_JSON } )
        @Path( "/{email}" )
        @GET
        public Person getPerson( @PathParam( "email" ) final String email ) {
            return peopleService.getByEmail( email );
        }
    
        @Produces( { MediaType.APPLICATION_JSON  } )
        @POST
        public Response addPerson( @Context final UriInfo uriInfo,
                @FormParam( "email" ) final String email, 
                @FormParam( "firstName" ) final String firstName, 
                @FormParam( "lastName" ) final String lastName ) {
            
            peopleService.addPerson( email, firstName, lastName );
            return Response.created( uriInfo
                .getRequestUriBuilder()
                .path( email )
                .build() ).build();
        }
        
        @Produces( { MediaType.APPLICATION_JSON  } )
        @Path( "/{email}" )
        @PUT
        public Person updatePerson( @PathParam( "email" ) final String email, 
                @FormParam( "firstName" ) final String firstName, 
                @FormParam( "lastName" )  final String lastName ) {
            
            final Person person = peopleService.getByEmail( email );
            
            if( firstName != null ) {
                person.setFirstName( firstName );
            }
            
            if( lastName != null ) {
                person.setLastName( lastName );
            }
    
            return person;              
        }
        
        @Path( "/{email}" )
        @DELETE
        public Response deletePerson( @PathParam( "email" ) final String email ) {
            peopleService.removePerson( email );
            return Response.ok().build();
        }
        
        public void setPeopleService( final PeopleService peopleService ) {
            this.peopleService = peopleService;
        }
    }

    我们可以看到,这里没有任何关于OSGi的信息 。 唯一的依赖是在某种程度上应该被注入PeopleRestServicePeopleService。 怎么样? 通常, OSGi应用程序使用蓝图作为依赖项注入框架,这与基于XML的老伙伴Spring配置非常相似。 它应该与应用程序一起打包在OSGI-INF / blueprint文件夹中。 这是在Apache CXF 3.0.1之上构建的REST模块的蓝图示例:

    <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
        xmlns:cxf="http://cxf.apache.org/blueprint/core"
        xsi:schemaLocation="
            http://www.osgi.org/xmlns/blueprint/v1.0.0 
            http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
            http://cxf.apache.org/blueprint/jaxws 
            http://cxf.apache.org/schemas/blueprint/jaxws.xsd
            http://cxf.apache.org/blueprint/jaxrs 
            http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
            http://cxf.apache.org/blueprint/core 
            http://cxf.apache.org/schemas/blueprint/core.xsd">
    
        <cxf:bus id="bus">
            <cxf:features>
                <cxf:logging/>
            </cxf:features>       
        </cxf:bus>
    
        <jaxrs:server address="/api" id="api">
            <jaxrs:serviceBeans>
                <ref component-id="peopleRestService"/>
            </jaxrs:serviceBeans>
            <jaxrs:providers>
                <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
            </jaxrs:providers>
        </jaxrs:server>
        
        <!-- Implementation of the rest service -->
        <bean id="peopleRestService" class="com.example.jaxrs.PeopleRestService">
            <property name="peopleService" ref="peopleService"/>
        </bean>         
        
        <reference id="peopleService" interface="com.example.services.PeopleService" />
    </blueprint>

    非常小而简单:基本上,配置仅指出为了使模块正常工作,应提供对com.example.services.PeopleService的引用(有效地由OSGi容器提供)。 为了了解它是如何发生的,让我们看一下另一个公开服务的模块。 它仅包含一个接口PeopleService

    package com.example.services;
    
    import java.util.Collection;
    
    import com.example.data.model.Person;
    
    public interface PeopleService {
        Collection< Person > getPeople( int page, int pageSize );
        Person getByEmail( final String email );
        Person addPerson( final String email, final String firstName, final String lastName );
        void removePerson( final String email );
    }

    并提供其实现作为PeopleServiceImpl类:

    package com.example.services.impl;
    
    import java.util.Collection;
    
    import org.osgi.service.log.LogService;
    
    import com.example.data.PeopleDao;
    import com.example.data.model.Person;
    import com.example.services.PeopleService;
    
    public class PeopleServiceImpl implements PeopleService {
        private PeopleDao peopleDao;
        private LogService logService;
     
        @Override
        public Collection< Person > getPeople( final int page, final int pageSize ) {        
            logService.log( LogService.LOG_INFO, "Getting all people" );
            return peopleDao.findAll( page, pageSize );
        }
    
        @Override
        public Person getByEmail( final String email ) {
            logService.log( LogService.LOG_INFO, 
                "Looking for a person with e-mail: " + email );
            return peopleDao.find( email );        
        }
    
        @Override
        public Person addPerson( final String email, final String firstName, 
                final String lastName ) {
            logService.log( LogService.LOG_INFO, 
                "Adding new person with e-mail: " + email );
            return peopleDao.save( new Person( email, firstName, lastName ) );
        }
    
        @Override
        public void removePerson( final String email ) {
            logService.log( LogService.LOG_INFO, 
                "Removing a person with e-mail: " + email );
            peopleDao.delete( email );
        }
        
        public void setPeopleDao( final PeopleDao peopleDao ) {
            this.peopleDao = peopleDao;
        }
        
        public void setLogService( final LogService logService ) {
            this.logService = logService;
        }
    }

    这次又一次是非常小的,干净的实现,它具有两个可注入的依赖项org.osgi.service.log.LogServicecom.example.data.PeopleDao 。 它的蓝图配置位于OSGI-INF / blueprint文件夹中,看起来也很紧凑:

    <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">
            
        <service ref="peopleService" interface="com.example.services.PeopleService" />        
        <bean id="peopleService" class="com.example.services.impl.PeopleServiceImpl">
            <property name="peopleDao" ref="peopleDao" />    
            <property name="logService" ref="logService" />
        </bean>
        
        <reference id="peopleDao" interface="com.example.data.PeopleDao" />
        <reference id="logService" interface="org.osgi.service.log.LogService" />
    </blueprint>

    预期由OSGi容器在运行时提供对PeopleDaoLogService的引用。 但是, PeopleService的实现是作为服务公开的,并且一旦其捆绑包被激活, OSGi容器将能够将其注入PeopleRestService

    难题的最后一部分,数据访问模块,稍微复杂一点:它包含持久性配置( META-INF / persistence.xml ),并且基本上依赖于OSGi容器的JPA 2.0功能。 persistence.xml非常基本:

    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        version="2.0">
     
        <persistence-unit name="peopleDb" transaction-type="JTA">
            <jta-data-source>
            osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=peopleDb)
            </jta-data-source>       
            <class>com.example.data.model.Person</class>
            
            <properties>
                <property name="openjpa.jdbc.SynchronizeMappings" 
                    value="buildSchema"/>         
            </properties>        
        </persistence-unit>
    </persistence>

    与服务模块类似, PeopleDao公开了一个接口:

    package com.example.data;
    
    import java.util.Collection;
    
    import com.example.data.model.Person;
    
    public interface PeopleDao {
        Person save( final Person person );
        Person find( final String email );
        Collection< Person > findAll( final int page, final int pageSize );
        void delete( final String email ); 
    }

    通过其实现PeopleDaoImpl

    package com.example.data.impl;
    
    import java.util.Collection;
    
    import javax.persistence.EntityManager;
    import javax.persistence.criteria.CriteriaBuilder;
    import javax.persistence.criteria.CriteriaQuery;
    
    import com.example.data.PeopleDao;
    import com.example.data.model.Person;
    
    public class PeopleDaoImpl implements PeopleDao {
        private EntityManager entityManager;
     
        @Override
        public Person save( final Person person ) {
            entityManager.persist( person );
            return person;
        }
     
        @Override
        public Person find( final String email ) {
            return entityManager.find( Person.class, email );
        }
     
        public void setEntityManager( final EntityManager entityManager ) {
            this.entityManager = entityManager;
        }
     
        @Override
        public Collection< Person > findAll( final int page, final int pageSize ) {
            final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
         
            final CriteriaQuery< Person > query = cb.createQuery( Person.class );
            query.from( Person.class );
         
            return entityManager
                .createQuery( query )
                .setFirstResult(( page - 1 ) * pageSize )
                .setMaxResults( pageSize ) 
                .getResultList();
        }
     
        @Override
        public void delete( final String email ) {
            entityManager.remove( find( email ) );
        }
    }

    请注意,尽管我们正在执行数据操作,但是没有提及事务,也没有对实体管理器的事务API的显式调用。 我们将使用声明式方法进行事务处理,因为蓝图配置支持(位置不变, OSGI-INF / blueprint文件夹):

    <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"  
        xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.1.0"
        xmlns:tx="http://aries.apache.org/xmlns/transactions/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">
        
        <service ref="peopleDao" interface="com.example.data.PeopleDao" />
        <bean id="peopleDao" class="com.example.data.impl.PeopleDaoImpl">
         <jpa:context unitname="peopleDb" property="entityManager" />
         <tx:transaction method="*" value="Required"/>
        </bean>
        
        <bean id="dataSource" class="org.hsqldb.jdbc.JDBCDataSource">
           <property name="url" value="jdbc:hsqldb:mem:peopleDb"/>
        </bean>
        
        <service ref="dataSource" interface="javax.sql.DataSource"> 
            <service-properties> 
                <entry key="osgi.jndi.service.name" value="peopleDb" /> 
            </service-properties> 
        </service>     
    </blueprint>

    要记住的一件事:应用程序不需要创建JPA 2.1的实体管理器: OSGi运行时能够做到这一点,并将其注入到需要的地方,由jpa:context声明驱动。 因此, tx:transaction指示运行时将选定的服务方法包装在事务中。

    现在,当提供最后一个服务PeopleDao时 ,我们准备使用Apache Karaf 3.0.1部署我们的模块。 三个步骤很容易做到:

    • 运行Apache Karaf 3.0.1容器
      bin/karaf (or bin\karaf.bat on Windows)
    • Apache Karaf 3.0.1 shell执行以下命令:
      feature:repo-add cxf 3.0.1
      feature:install http cxf jpa openjpa transaction jndi jdbc
      install -s mvn:org.hsqldb/hsqldb/2.3.2
      install -s mvn:com.fasterxml.jackson.core/jackson-core/2.4.0
      install -s mvn:com.fasterxml.jackson.core/jackson-annotations/2.4.0
      install -s mvn:com.fasterxml.jackson.core/jackson-databind/2.4.0
      install -s mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/2.4.0
      install -s mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/2.4.0
    • 构建我们的模块并将其复制到Apache Karaf 3.0.1的deploy文件夹(容器仍在运行时):
      mvn clean package
      cp module*/target/*jar apache-karaf-3.0.1/deploy/

    Apache Karaf 3.0.1 Shell中运行list命令时,应该看到所有激活的捆绑软件(模块)的列表,类似于以下列表:

    apache-karaf列表
    其中module-servicemodule-jax-rsmodule-data对应于我们正在开发的模块。 默认情况下,我们所有的Apache CXF 3.0.1服务将在基本URL http:// :8181 / cxf / api /上提供。 通过在Apache Karaf 3.0.1 shell中执行cxf:list-endpoints -f命令很容易检查。

    apache-karaf-cxf-list-endpoints

    让我们通过发送几个HTTP请求来确保REST层按预期工作。 让我们创建一个新人:

    curl http://localhost:8181/cxf/api/people -iX POST -d "firstName=Tom&lastName=Knocker&email=a@b.com"
    
    HTTP/1.1 201 Created
    Content-Length: 0
    Date: Sat, 09 Aug 2014 15:26:17 GMT
    Location: http://localhost:8181/cxf/api/people/a@b.com
    Server: Jetty(8.1.14.v20131031)

    并验证此人已成功创建:

    curl -i http://localhost:8181/cxf/api/people
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    Date: Sat, 09 Aug 2014 15:28:20 GMT
    Transfer-Encoding: chunked
    Server: Jetty(8.1.14.v20131031)
    
    [{"email":"a@b.com","firstName":"Tom","lastName":"Knocker"}]

    检查数据库是否也有人填充会很好。 使用Apache Karaf 3.0.1 shell,只需执行两个命令即可轻松完成: jdbc:datasourcesjdbc:query peopleDb“ select * from people”

    apache-karaf-list-datasources

    太棒了! 我希望这篇介绍性很强的博客文章能打开另一篇有趣的技术,您可以将其用于开发健壮,可伸缩,模块化和可管理的软件。 我们没有涉及很多东西,但是您可以在这里找到它们。 完整的源代码可在GitHub找到

    Hibernate 4.2.x / 4.3.x用户注意:不幸的是,在当前版本的Apache Karaf 3.0.1中Hibernate 4.3.x完全可以正常工作(因为尚不支持JPA 2.1 ),但是我设法做到了与Hibernate 4.2.x一起运行时,容器通常拒绝解析与JPA相关的依赖关系。

    翻译自: https://www.javacodegeeks.com/2014/08/osgi-the-gateway-into-micro-services-architecture.html

    osgi架构与linux

    展开全文
  • 基于OSGi架构的面向服务组件编程,赵林虎,,OSGi(Open Services Gateway Initiative,开放服务网关协议) 提供了一个面向服务组件编程模型。通过OSGi 框架可以轻松构建组件,同时组件与组件之
  • OSGi架构研究

    2009-07-31 00:04:32
    OSGi架构研究 OSGi概述  OSGi是Open Service Gateway Initiative的简称,该组织建立于1999年,是一个非赢利机构,旨在建立一个开放的服务规范,为通过网络向设备提供服务建立开放的标准。OSGi并不是专为家庭网络...

    OSGi架构研究

    OSGi概述

           OSGiOpen Service Gateway Initiative的简称,该组织建立于1999年,是一个非赢利机构,旨在建立一个开放的服务规范,为通过网络向设备提供服务建立开放的标准。OSGi并不是专为家庭网络而制定的,除了住宅网关,像车载电脑等其他移动嵌入式设备也都可以通过OSGi接入Internet,获取不同的应用服务。它为服务供应商、软件供应商、网关开发人员以及设备供应商提供了一个开放、通用的架构,使它们能互动地开发、部署和管理服务。其软件环境基于Sun JAVA虚拟机,并不涉及具体的连接协议。对于任何新设备,它都能够灵活地将其纳入现有网络。可以使用OSGi的对象包括各种数字和模拟的机顶盒、服务网关、有线电视电缆调制解调器、消费类电子产品、PC、工业计算机、汽车等。

     

    OSGi体系结构

    以下是一张OSGi的体系结构图:

    从上图的层次结构可以看出,Native Operating System层代表的是本地硬件与操作系统,Java VM层为跨平台应用提供了可能。而再往上,就是OSGi framework了。

    Bundle实际就是一个具有jar(Java ARchive)格式的文件,其中包含了javaclass文件和其他资源文件(比如图标,配置文件等等)。Bundle可以在自己的manifest 文件中说明自己能够提供哪些java包,其他bundle如果在自己的manifest文件中指定了它需要这个包,那他们之间就可能产生java包的依赖关系,这样多个bundle之间就可以共享java包。

    OSGiR4中将功能分为几层,包括:安全层、模块层、生命周期层、服务层和实际的服务。OSGi的核心实现即为OSGi框架,它本身也是一个OSGi Bundle

    名称()

    职责或功能

    Security(安全层)

    OSGi环境中应用的部署和管理提供更好的安全控制。

    Modules(模块层)

    主要负责bundle的安装部署,更新和卸载。

    Life Cycle(生命周期层)

    Bundle组件的安全和生命周期操作提供了API定义,该层位于安全层和模块层之上。

    Services(服务层)

    定义了一个与生命周期层紧密结合的组件动态交互模型。OSGi中的服务是实现了一个或多个Java接口的Java对象,通过将这些对象依据其实现的接口注册到服务注册表中,Bundle组件可以发布自己的服务,查找使用服务,注册监听处理服务的状态变更等。

    Actual Services(实际的服务)

    OSGi定义的一些标准的服务接口如日志服务(Log Service),包管理服务(Package Admin Service)、启动级别服务(Start Level Service)、HTTP服务(Http Service)、配置服务(Config Admin Service)、用户管理服务(User Admin Service)等。

     

    OSGi容器

    现在比较流行的开放源码的OSGi容器有以下三种:

     

    a)  Equinox容器是参照OSGi规范第4版实现的,它构成了Eclipse IDE的核心—模块化的Java运行时;它实现了OSGi规范4中规定的必须强制实现的功能,同时,它也实现了OSGi规范中大部分的可选功能;

     

    b) KnoflerfishOSGi规范第3版和第4版的开源实现,它实现了OSGi规范规定的必须实现的功能及部分可选功能;

     

    c) ApacheFelixApache软件基金会实现的OSGi开源容器。

     

     


    OSGi项目实践

    技术是做出来的,不是想出来的。

    以下,我将使用Equonix作为OSGi容器,来做一个小项目,将一天以来学习到的知识用到具体实践之中。

    便携设备越来越多,连家庭主妇身边都可能有个PDA或者智能手机,优秀的家庭主妇都是管帐的高手,相信做一个支出管理系统会大卖特卖。现在忽略PDA或是智能机用的是什么硬件配置以及接口,用Swing来模拟前端界面。

     

    我把这个系统命名为ExpenseManager,下面是系统的包结构:

     

     

    pratice.domain       用来放实体类

    pratice.service       存放支出管理系统提供服务的接口及其实现类

    pratice.uri              界面相关的类

     

    完成1.0版时的包结构如下:



     

     

    其中,Expense是代表一条消费记录的实体类,其定义如下:

    public class Expense {

       

        private int id;          //消费ID

        private String date; //消费时间

        private String item; //消费项目

        private float money;     //消费额

       

        public String getDate() {

           return date;

        }

        public void setDate(String date) {

           this.date = date;

        }

    ……//省略其它属性get,set方法

    }

    ExpenseDB类代表一个存储消费记录的数据库表,提供插入,检索数据,查询列名等操作,类图如下:





     

     
     
     

    ExpenseManagerService是系统的服务接口,定义系统可以向外提供的功能,在1.0版中只实现了增加支出记录功能,以后可逐步增加诸如,删除,修改,统记等功能。下面给出接口及其实现类代码:

     

    public interface ExpenseManagerService {

        public void addExpense(Expense expense);

    }

     

    public class ExpenseManagerServiceImpl implements ExpenseManagerService {

        private ExpenseDB expenseDB;

        public ExpenseManagerServiceImpl(ExpenseDB expenseDB) {

           this.expenseDB = expenseDB;

        }

        public void addExpense(Expense expense) {

           expenseDB.addExpense(expense);

        }

    }

     

    ExpenseManagerURI类是界面类,也是bundle中的Activator,继续自JFrame,同时实现BundleActivator接口。只要在MANIFEST.MF中指定

    Bundle-Activator: pratice.uri.ExpenseManagerURI

    framework就能通过ClassLoader找到pratice.uri.ExpenseManagerURI.class并加载后,就可以通过newInstance()方法创建一个BundleActivator的实例,然后调用public void start(BundleContext context)方法和void stop(BundleContext context)方法来管理bundle的生命周期。代码略。

           AddExpenseDialog是增加支出记录的对话框。

     

    MANIFEST.MF文件内容如下:

    Manifest-Version: 1.0

    Bundle-ManifestVersion: 2

    Bundle-Name: ExpenseManager Plug-in

    Bundle-SymbolicName: ExpenseManager

    Bundle-Version: 1.0.0

    Bundle-Activator: pratice.uri.ExpenseManagerURI

    Bundle-Localization: plugin

    Import-Package: org.osgi.framework;version="1.3.0"

     

    布署到Equonix容器后,执行效果见下图:




     
     

     

    点击添加记录,跳出加支出记录的对话框。



     

    输入数据提交后,在管理系统界面点击支出列表,罗列出支出记录。

     

    为显示OSGi架构支持即插即用,动态部署的特性,在1.1版中增加统计消费额的功能,只要执行Equonix框架提供的更新命令,framework就完成对bundle的升级工作。为此,对源代码进行相应修改。

    ExpenseManagerService接口增加统计方法,实现类与ExpenseDB类作相应修改。

     

    public interface ExpenseManagerService { 

        public void addExpense(Expense expense);

        public float sumAllCost();

    }

    public class ExpenseManagerServiceImpl implements ExpenseManagerService {

        private ExpenseDB expenseDB;

        public ExpenseManagerServiceImpl(ExpenseDB expenseDB) {

           this.expenseDB = expenseDB;

        }

        public void addExpense(Expense expense) {

           expenseDB.addExpense(expense);

        }

        public float sumAllCost() {

           return expenseDB.sumAllCost();

        }

    }

    public class ExpenseDB {

       

        private List<Expense> expenseList;

    ……//其余代码省略

        public float sumAllCost() {

           float sum = 0;

           for(int i = 0; i <= expenseList.size(); i++ ){

               sum += ((Expense)expenseList.get(i)).getMoney();

           }

           return sum;

        }

    }

    MANIFEST.MF文件内容如下:

    Manifest-Version: 1.0

    Bundle-ManifestVersion: 2

    Bundle-Name

    展开全文
  • OSGI架构设计

    2019-11-11 15:54:14
    OSGI在国内不常用,而且相关资料比较少,很早之前在2015年的时候,公司有机会拿此框架做过一个项目,还算成功,所以在此分享一下OSGI的相关内容。 一、什么是OSGI? Open Service Gateway Initiative,官方说的很...

    OSGI在国内不常用,而且相关资料比较少,很早之前在2015年的时候,公司有机会拿此框架做过一个项目,还算成功,所以在此分享一下OSGI的相关内容。

    一、什么是OSGI?

    Open Service Gateway Initiative,官方说的很明白,上网一搜介绍也有一堆,在此就不详细搬述了,也没啥意义。但是根据项目中对osgi的实战,想说说我个人的理解,我个人总结的是osgi是一个非常好的模块化、组件化的生态系统。它解决了软件设计最重要的三个主题:复用、内聚、耦合。并且提供了设计层面的一种规范,将模块化思想发挥到了极致。这是我个人对它的总结概述。

     

    二、为什么要使用OSGI(优势)?

    整体上来说,当然是osgi对模块化有很好的支持。
    具体从开发角度来看:
    1、复杂性的降低:基于OSGI的组件模型bundle能够隐藏内部实现,而bundle是基于服务进行交互。
    2、复用性强:因为是模块化,很多第三方的组件都可以以bundle的形式进行复用。
    3、简单:核心API总数不超过30个类和接口。
    4、小巧:OGGI R4框架的实现仅需要300k jar就足够了。系统中引入osgi基本上没有什么开销。
    5、非侵入式:服务可以以POJO形式实现,不需要关注特定接口。
    从部署角度来说:
    1、动态更新:也是OSGI最常被提起的一个特性,所谓的热部署,任何一个bundle都可以动态的安装、启动、停止、更新和卸载,但是不需要重启整个系统,是不是很牛。
    2、适配性:OSGI提供的服务机制、组件可以动态的注册、获取和监听服务,使得系统能够在osgi环境调整自己的功能。
    3、透明:提供了管理API来访问内部状态,因此通常无需去查看日志,能够通过命令进行调试。
    4、版本化:bundle可以版本化,多版本共存而不影响整个系统功能,解决了JAR Hell问题。
    5、快速:OSGI的类加载机制,和Jar包的线程加载不同,bundle委托式的类加载机制,使得类加载无需搜索,而且又能有效的加快系统的启动速度。
    6、懒加载:OSGI也提供了懒加载机制,比如服务可以被注册,直到使用时才被创建。
    OSGI的安全层面当然也是ok的,因为其本身就提供了一个安全层,基于java安全模型增加了可用性。

     

    三、OSGI适用于哪些项目?

    如果你想把你的系统设计成流行的模块化的方式,这些模块需要支持随时启动,停止,更新操作并且对你的系统或者其他模块造成的影响最小,OSGI是最理想的选择。每个模块都是自治的,它们可以自己解决模块依赖传递关系而不需要在容器层解决这些问题。但是这里我要强调一点,模块化的实现并不是只有OSGI。遵守良好的开发习惯和设计,模块间适当隔离,这不就是模块化吗?如果你的场景是动态化的,毫无疑问,OSGI将是最佳选择。
    OSGI构建最著名的应用当属Eclipse了,为了让eclipse成为更动态化的富客户端平台并增强这个平台的模块化,eclipse团队最终选择osgi框架作为运行时模块系统(该项目成为equinox)。这个新版本的eclipse中有一个基于osgi的运行时模型。osgi不再只是用于嵌入式软件以及网络设备中的技术,而是成为所有eclipse插件开发的基础,成百上千开发人员也使用该平台上的eclipse IDE来开发软件。
     

    四、OSGI整体架构

    主要分为Security Layer、Module Layer、Lift Cycle Layer、Service Layer。

    Security Layer:

    Module Layer:

    Lift Cycle Layer:

    Service Layer:

     

    五:重要基本概念及特性介绍

    模块化相关

    OSGI框架定义了一个模块化单元,称为bundlue,只是一个jar文件。
    如何判定是osgi bundle?jar包含了提供功能的资源以及关于bundle元数据的清单文件(manifest)。
    资源可以是什么?资源可以是java类、html、图片、servlet甚至jsp。
    改变了什么?改变了企业级应用程序的部署模型,传统web的思考方式是以web应用开发为中心的。现在你只需要开发组成应用程序的bundle,所以将从以应用为中心转移到以模块为中心。

    管理依赖相关

    管理关系的模式是Manifest导入导出包。
    发布接口模式是单纯依赖Java,不可能将类型隐藏在模块中。
    物理分层模式是必须导入Bundle所要使用所有包,通过检查清单文件来保证没有导入任何展现相关的类。

    Osgi uService相关

    BluePrint相关

    简单来说BluePrint就是让我们的代码独立于OSGI API。说到blueprint,务必需要提及一下Spring,Spring框架对于开发Java的一定不会陌生,其子项目中SpringBoot也成为业界微服务一大选择。而在osgi中,Spring最初也有所涉及,为Spring DM,Blueprint产生的规范便是起源于Spring DM,随后好像Spring DM没有继续发展,但是BluePrint却是一直存在。目前,BluePrint规范主要有两个实现:Aries BluePrint和Gemini BluePrint,它们分别来自Apache和Eclipse两个开源组织。我们日后讲的基本都是Apache官网中的BluePrint。

     

    六:OSGI运行的容器

    OSGI运行的容器现在支持最好的当属Apache旗下的Karaf。
    Karaf是Apache旗下的一个开源项目.Karaf。同时也是一个基于OSGI的运行环境。Karaf提供了一个轻量级的OSGI容器,可以用于部署各种组件和应用程序。Karaf提供了很多特性用于帮助开发者和用户更加灵活的部署应用,比如热部署、动态配置,几种日志处理系统,本地系统集成,可编程扩展控制台,ssh远程访问,内置安装认证机制等等。同时Karaf作为一款成熟而且优秀的OSGI运行环境以及容器已经被众多Apache项目作为基础容器,比如上面提到的Apache Geronimo,Apache ServiceMix,Fuse ESB,由此可见,Karaf在性能上,功能和稳定性上都是个不错的选择。具体Karaf的一些介绍可以参照下图:

     

    七、实战

    具体代码略,有需要的可以留言,在此就不公开了。运行效果如下:

    展开全文
  • 摘要:嵌入式计算应用已经广泛运行在各种平台,普遍应用于各个领域,文中主要介绍在嵌入式系统上运行OSGI架构的相关操作和运行。 关键词:虚拟机;OSGI架构How to Run on OSGI Architecture for Embedded Systems WEN ...

    http://www.14edu.com/ligong/jisuanji/050225M22010.html

     

    本文作者(文林莉 杨 兴 吴名),请您在阅读本文时尊重作者版权。

    摘要:嵌入式计算应用已经广泛运行在各种平台,普遍应用于各个领域,文中主要介绍在嵌入式系统上运行OSGI架构的相关操作和运行。

    关键词:虚拟机;OSGI架构How to Run on OSGI Architecture for Embedded Systems

    WEN Lin-li, YANG Xing, WU Ming-zhang

    (School of Economics Management, Guangdong Institute of Science Technology, Zhuhai 519090, China)

    Abstract: A wide range of embedded computing applications running on various platforms have been widely used in various fields, this paper introduces an embedded system running on OSGI architecture related to the operation and running.

    Key words: virtual machine; OSGI architecture

    目前,嵌入式计算应用已经广泛运行在各种平台,普遍应用于各个领域。如何实现运行在动态环境,或不同平台的这些应用之间的相互发现和交互,或这些应用程序如何根据设备和服务环境的变化自动灵活的动态配置和扩充是近年来研究的一个热点。OSGI规范是嵌入式应用“智能化”发展所需求的一个开放、通用的解决方案。

    1 OSGI介绍

    OSGI是Open Servicc Gateway Initiative的简称,该组织建立于1999年,是一个非赢利机构,旨在建立一个开放的服务规范,为通过网络向设备提供服务建立开放的标准。OSGI规范为网络服务定义了一个标准的、面向组件的计算环境。软件组件可以从运行中被安装、升级或者移除而不需要中断设备的操作。软件组件可以动态地发现和使用其他库或者应用程序。下面具体讲解一下OSGI的运行机制[1-2]。

    OSGI[3]框架是一个微核结构的容器,所有的模块都需要运行在容器范围内,在OSGI中所有模块的部署都必须以Bundle的方式来进行部署。所谓Bundle其实就是一个jar文件,这个jar文件和普通的jar文件唯一不同的地方就是Meta-inf目录下的MANIFEST.MF文件的内容,关于Bundle的所有信息都在MANIFEST.MF中进行描述,可以称它为bundle的元数据,这些信息中包含有象Bundle的名称、描述、开发商、classpath、需要导入的包以及输出的包等。

    Bundle通过实现BundleActivator接口去控制其生命周期,在Activator中编写Bundle[4]启动、停止时所需要进行的工作,同时也可以在Activator中发布或者监听框架的事件状态信息,以根据框架的运行状态做出相应的调节。

    2 选择合适的虚拟机

    选择一种合适的虚拟机是很重要的,选择的虚拟机要满足OSGI架构最基本的运行条件,虚拟机的种类比较多,有kaff,j9,wonka,cvm,kvm,jre等,当中有运行在X86上的,也有运行在嵌入式设备上的,根据OsgiAllance说法,OSGI架构运行的最小环境是(KVM CLDC DIDP,CDC CVM FP)。一开始选择了KVM作为运行OSGI的虚拟机,由于KVM的资源有限,就连一个JAR文件也运行不了,后来更换了CVM作为虚拟机,经过一些简单的配置后,成功编译,OSGI架构也成功地运行了。

    3 编译CVM虚拟机

    SUN的JVM开源后,作为JAVA开发社区的一个项目,为避免版权问题,J2ME改名为phoneME。CLDC对应phoneME Feature,虚拟机则称为KVM;而CDC对应phoneMEAdvance,虚拟机则称为CVM。这里选择了phoneme_advanced-mr2-dev-src-b34-04_oct_2007.zip

    unzip phoneme_advanced-mr2-dev-src-b34-04_oct_2007.zip

    cd cdc

    cd build

    cd linux-arm

    vi defs.mk

    将ifneq ($(CVM_FORCE_HARD_FLOAT), true)

    ifeq ($(USE_GCC2), true)

    CC_ARCH_FLAGS = -msoft-float

    ASM_ARCH_FLAGS = -msoft-float

    LINK_ARCH_FLAGS = -msoft-float

    LINK_ARCH_LIBS = -lfloat

    CVM_TARGETOBJS_OTHER = _fixunsdfsi.o

    endif

    endif

    改为:

    将ifneq ($(CVM_FORCE_HARD_FLOAT), true)

    ifeq ($(USE_GCC2), true)

    LINK_ARCH_FLAGS =

    LINK_ARCH_LIBS = -lm

    endif

    endif

    cd ../linux-arm-familiar

    make J2ME_CLASSLIB=foundation CVM_TARGET_TOOLS_PREFIX=/usr/local/arm/3.3.2/bin/arm-linux- CVM_HOST_TOOLS_PREFIX =/usr/bin/ CVM_CLASSLOADING=true CVM_JAVA_TOOLS_PREFIX=/home/wmz/kvm/j2sdk1.4.2_18/bin/ JDK_HOME=/home/wmz/kvm/j2sdk1.4.2.18/bin/ CC_ARCH_FLAGS=-mcpu=arm920t

    如果编译没有什么错误的话,就在linux-arm-familiar的bin目录下生成CVM,在linux-arm-familiar目录也同时生成:testclasses.zip,democlasses.jar等测试文件,以及btclasses.zip和lib文件夹等库文件(lib文件夹里有foundation.jar,content-types.properties,以及security,zi等两个文件夹)。当在开发的时候,需要把btclasses.zip放到lib文件夹里,作为一个基础类库。

    在编译CVM的时候,同时也将CDC自带的测试程序编译出来了,testclasses.zip,democlasses.jar就是测试文件。把btclasses.zip放到lib文件夹里,将lib,bin文件夹,以及 testclasses.zip,democlasses.jar下载到开发板里,接下来就是运行测试程序了[5]。如果是直接下载cvm到开发板的话,一定要建立一个bin文件夹,将cvm放到bin文件夹中,这样才能完成运行。

    执行bin/cvm –version如果能得到如下输出的话证明你的CVM能运行。

    接下来测试个HelloWorld.

    bin/cvm-cp testclasses.zip HelloWorld

    应该得到下面的结果:

    最后做一次全面的测试:

    bin/cvm-cp testclasses.zip Test

    如果是和下面的结果一样的话,就说明移植的cvm完全没有问题。

    安装OSGI架构到开发板中,在开源界中实现OSGI的框架比较知名的有:Equinox、Knopflerfish、Oscar。

    1)Equinox

    Equinox是Eclipse中的项目之一,Equinox是作为OSGI R4 RI而知名的,同时由于Equinox有Eclipse IDE这么个成功案例,反应出了Equinox作为OSGI框架的优势。Equinox开发小组由IBM的Jeff领衔,开发状态非常的活跃,从它的开发者maillist可以看出,讨论非常的热烈。

    2)Oscar

    Oscar是一个遵循OSGI R3框架的实现,目前它的开发状态不怎么的活跃,最新的新闻都是2005年的了。 Oscar的优势在于提供了大量OSGI R3标准之外的Bundle,为开发基于OSGI的系统提供了方便。

    3)Knopflerfish

    Knopflerfish是一个知名的OSGI框架,目前提供的最新版本也已经完整的实现了OSGI R4,Knopflerfish的开发状态非常的活跃,同时它也提供了为方便开发基于OSGI系统的大量的Bundle。

    安装OSGI架构只须将X架构下载到开发板中就可以,然后通过指令:cvm –jar X..jar启动架构。

    下面是安装equinox的实例,运行:bin/cvm –jar equinox.jar -console

    接下来就是安装一些运用bundle了,至此已经完成了将OSGI架构安装到开发板上的全部过程。

    4 结束语

    本文通过选择合适的虚拟机到编译CVM虚拟机,直到完成并安装OSGI架构到开发板中,这一系列的操作说明在嵌入式系统上运行OSGI架构是可行的,而且也取得了不错的运行测试效果,这为后期的实际应用打下了基础。

    参考文献:

    [1] 张亚楠.基于OSGI的持续集成系统[J].软件导刊,2009(6):32-33.

    [2] OSGi原理与最佳实践[EB/OL].http://www.huachu.com.cn/itbook/bookinfodetail.asp?lbbh=10107999 sort=qy.

    [3] 宋明秋,李嘉华,邓贵仕.基于混合加密的OSGi认证协议[J].计算机工程,2007(1):133-135.

    [4] 相东飞.基于OSGi插件化的应用框架[J].科技信息,2007(12):178-179.

    [5] 基于OSGi的面向服务的组件编程(2)[EB/OL].http://hi.baidu.com/dabo12/blog/item/fa8a5b8d4be3c210b21bba45.html.

    展开全文
  • 伦敦OSGi与会者可以享受与OSGi相关的全天活动,包括演示和教程,以及非常特殊的OSGi社区活动 ,该活动将重点关注基于OSGi标准架构的实际实现和好处。 “ OSGi的价值:现在和现在”社区活动还将提供有关使用OSGi迁移...
  • OSGi架构学习与设计

    千次阅读 2011-11-26 21:06:30
    首先,我想表扬自己终于开始实践自己...Equinox是Eclipse内的一个简单的开源OSGi框架,在它的基础上,我需要自己创建我所需要的bundles。框架底层衔接的是一个其他项目组正在开发中的非结构化数据库,而框架之上是一
  • 在这篇文章中,我将高层次地介绍OSGi架构以及Bundle的生命周期,相信大家读完这篇以后,可以对OSGi有个高屋建瓴的认识。   OSGi架构如下图所示,主要包括以下几个层次:执行环境(Execution Environment...
  • 一、Bean 组件管理器 用过Hibernate 的童鞋应该知道这个原理,废话不多说看看代码就知道。   ...这里是一个具体的实现 它可以同时引用多个服务接口,不多说看了就会明白 ...这里申明一个服务的引用,并在程序一开始...
  • http://jinsuo2007.blog.163.com/blog/static/192279952010106113845634/ 目前,嵌入式计算应用已经广泛运行在各种平台,普遍应用于各个领域。如何实现运行在动态环境,或不同... 1 OSGI介绍 OSGI是Open Servicc Gatew
  •  OSGI的体系架构是基于插件式的软件结构,包括一个 OSGI 框架和一系列插件,在 OSGI中,插件称为 Bundle,其中,OSGI框架规范是OSGI规范的核心部分,它提供了一个通用的、安全可管理的 Java 框架,通过这个框架...
  • OSGi服务:SOA的架构

    千次阅读 2011-12-18 21:16:43
    OSGi架构非常适合我们实现面向服务的应用(SOA)。OSGi具有隐藏真实的服务实现类的能力,所以它为面向服务的应用提供了良好的类与接口的组合。 OSGi服务 前面我们提到,OSGi架构非常适合我们实现面向服务...
  • 摘要: OSGI架构一个服务端, 满足可插拔, 低耦合, 重用率高的问题. 并且服务端接收到指定协议的数据后, 能自动分发到相应的服务进行处理。 目的是为了满足后期的可插拔特性。本文是服务端设置的一个Demo. 后期这个...
  • OSGi服务:非常适合SOA的架构

    千次阅读 2012-09-23 14:31:16
    OSGi架构非常适合我们实现面向服务的应用(SOA)。OSGi具有隐藏真实的服务实现类的能力,所以它为面向服务的应用提供了良好的类与接口的组合。 本文是《你好,OSGi》系列的第四部分。下面讲述OSGi服务。对OSGi...
  • 软件架构-OSGi

    2019-10-16 10:16:06
    软件架构-OSGi参考资料OSGi 的由来和本质特性 OSGi 的由来和本质特性 OSGi的类加载机制和模型,OSGi的用处,版本冲突的解决方法等等 [https://www.cnblogs.com/doit8791/p/6049337.html] ...
  • osgi.net 在构建可扩展,可靠的分布式系统的背景下,“模块化”和“微服务体系结构”这两个术语如今经常出现。 众所周知,Java平台本身在模块化方面很弱( Java 9将通过交付Jigsaw项目来解决此问题),从而为OSGi和...
  • 大纲【osgi和微服务spring cloud是两种思路的架构osgi:面对模块开发热插拔,可以将功能模块化,热插拔到任何系统,大大降低重复的设计,但是osgi要求开发者对中心的抽象能力要求极强。osgi还可以节约运营成本,...
  • 博客配套的 说明 ppt ,详细介绍了 架构开发背景,使用技术,等等细节。
  • OSGI for C++ - 通往架构师之路

    万次阅读 多人点赞 2020-02-28 17:25:37
    OSGI 技术是面向 Java 的动态模型系统。Java 圈子里有非常著名的一句话:OSGI - 架构师的天堂。换句话说,OSGI 能让软件开发变得更加容易!
  • OSGI基础学习

    2014-01-16 20:45:32
    OSGI:开发服务网关,实际上是一个由OSGI联盟发起的以JAVA为技术平台的动态模块化...小型系统使用OSGI架构会增加开发成本,OSGI架构适用于大型企业级的应用开发。目前,OSGI架构并不是很稳定,就日前在实习公司使用的
  • Java应用架构设计模块化模式与OSGi

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,074
精华内容 3,629
关键字:

osgi架构