免费制作app生成器网站济南网站建设运营
web/
2025/10/2 10:48:43/
文章来源:
免费制作app生成器网站,济南网站建设运营,长沙房产网最新楼盘,爱演示网osgi架构与linux在构建可扩展#xff0c;可靠的分布式系统的背景下#xff0c;“模块化”和“微服务体系结构”这两个术语如今经常出现。 众所周知#xff0c;Java平台本身在模块化方面很弱#xff08; Java 9将通过交付Jigsaw项目来解决此问题#xff09;#xff0c;这为… osgi架构与linux 在构建可扩展可靠的分布式系统的背景下“模块化”和“微服务体系结构”这两个术语如今经常出现。 众所周知Java平台本身在模块化方面很弱 Java 9将通过交付Jigsaw项目来解决此问题这为OSGi和JBoss 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 开始一直到底部数据访问因为它更容易遵循。 我们的PeopleRestService是JAX-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 } )GETpublic Collection Person getPeople( QueryParam( page) DefaultValue( 1 ) final int page ) {return peopleService.getPeople( page, 5 );}Produces( { MediaType.APPLICATION_JSON } )Path( /{email} )GETpublic Person getPerson( PathParam( email ) final String email ) {return peopleService.getByEmail( email );}Produces( { MediaType.APPLICATION_JSON } )POSTpublic 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} )PUTpublic 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} )DELETEpublic Response deletePerson( PathParam( email ) final String email ) {peopleService.removePerson( email );return Response.ok().build();}public void setPeopleService( final PeopleService peopleService ) {this.peopleService peopleService;}
} 我们可以看到这里没有任何关于OSGi的信息 。 唯一的依赖是在某种程度上应该被注入PeopleRestService的PeopleService。 怎么样 通常 OSGi应用程序使用蓝图作为依赖项注入框架这与基于XML的老伙伴Spring配置非常相似。 它应该与应用程序一起打包在OSGI-INF / blueprint文件夹中。 这是在Apache CXF 3.0.1之上构建的REST模块的蓝图示例 blueprint xmlnshttp://www.osgi.org/xmlns/blueprint/v1.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:jaxrshttp://cxf.apache.org/blueprint/jaxrsxmlns:cxfhttp://cxf.apache.org/blueprint/corexsi:schemaLocationhttp://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsdhttp://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsdhttp://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsdhttp://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsdcxf:bus idbuscxf:featurescxf:logging//cxf:features /cxf:busjaxrs:server address/api idapijaxrs:serviceBeansref component-idpeopleRestService//jaxrs:serviceBeansjaxrs:providersbean classcom.fasterxml.jackson.jaxrs.json.JacksonJsonProvider //jaxrs:providers/jaxrs:server!-- Implementation of the rest service --bean idpeopleRestService classcom.example.jaxrs.PeopleRestServiceproperty namepeopleService refpeopleService//bean reference idpeopleService interfacecom.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;Overridepublic Collection Person getPeople( final int page, final int pageSize ) { logService.log( LogService.LOG_INFO, Getting all people );return peopleDao.findAll( page, pageSize );}Overridepublic Person getByEmail( final String email ) {logService.log( LogService.LOG_INFO, Looking for a person with e-mail: email );return peopleDao.find( email ); }Overridepublic 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 ) );}Overridepublic 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.LogService和com.example.data.PeopleDao 。 它的蓝图配置位于OSGI-INF / blueprint文件夹中看起来也很紧凑 blueprint xmlnshttp://www.osgi.org/xmlns/blueprint/v1.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsdservice refpeopleService interfacecom.example.services.PeopleService / bean idpeopleService classcom.example.services.impl.PeopleServiceImplproperty namepeopleDao refpeopleDao / property namelogService reflogService //beanreference idpeopleDao interfacecom.example.data.PeopleDao /reference idlogService interfaceorg.osgi.service.log.LogService /
/blueprint 预期由OSGi容器在运行时提供对PeopleDao和LogService的引用。 但是 PeopleService的实现是作为服务公开的并且一旦其捆绑包被激活 OSGi容器将能够将其注入PeopleRestService 。 难题的最后一部分数据访问模块稍微复杂一点它包含持久性配置 META-INF / persistence.xml 并且基本上依赖于OSGi容器的JPA 2.0功能。 persistence.xml非常基本 persistence xmlnshttp://java.sun.com/xml/ns/persistencexmlns:xsihttp://www.w3.org/2001/XMLSchema-instanceversion2.0persistence-unit namepeopleDb transaction-typeJTAjta-data-sourceosgi:service/javax.sql.DataSource/(osgi.jndi.service.namepeopleDb)/jta-data-source classcom.example.data.model.Person/classpropertiesproperty nameopenjpa.jdbc.SynchronizeMappings valuebuildSchema/ /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;Overridepublic Person save( final Person person ) {entityManager.persist( person );return person;}Overridepublic Person find( final String email ) {return entityManager.find( Person.class, email );}public void setEntityManager( final EntityManager entityManager ) {this.entityManager entityManager;}Overridepublic 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();}Overridepublic void delete( final String email ) {entityManager.remove( find( email ) );}
} 请注意尽管我们正在执行数据操作但是没有提及事务也没有对实体管理器的事务API的显式调用。 我们将使用声明式方法进行事务处理因为蓝图配置支持位置不变 OSGI-INF / blueprint文件夹 blueprint xmlnshttp://www.osgi.org/xmlns/blueprint/v1.0.0 xmlns:jpahttp://aries.apache.org/xmlns/jpa/v1.1.0xmlns:txhttp://aries.apache.org/xmlns/transactions/v1.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsdservice refpeopleDao interfacecom.example.data.PeopleDao /bean idpeopleDao classcom.example.data.impl.PeopleDaoImpljpa:context unitnamepeopleDb propertyentityManager /tx:transaction method* valueRequired//beanbean iddataSource classorg.hsqldb.jdbc.JDBCDataSourceproperty nameurl valuejdbc:hsqldb:mem:peopleDb//beanservice refdataSource interfacejavax.sql.DataSource service-properties entry keyosgi.jndi.service.name valuepeopleDb / /service-properties /service
/blueprint 要记住的一件事应用程序不需要创建JPA 2.1的实体管理器 OSGi运行时能够做到这一点并将其注入到需要的地方由jpacontext声明驱动。 因此 txtransaction指示运行时将选定的服务方法包装在事务中。 现在当提供最后一个服务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命令时应该看到所有激活的捆绑软件模块的列表类似于以下列表 其中module-service module-jax-rs和module-data对应于我们正在开发的模块。 默认情况下我们所有的Apache CXF 3.0.1服务将在基本URL http// 8181 / cxf / api /上提供。 通过在Apache Karaf 3.0.1 shell中执行cxflist-endpoints -f命令很容易检查。 让我们通过发送几个HTTP请求来确保REST层按预期工作。 让我们创建一个新人 curl http://localhost:8181/cxf/api/people -iX POST -d firstNameTomlastNameKnockeremailab.comHTTP/1.1 201 Created
Content-Length: 0
Date: Sat, 09 Aug 2014 15:26:17 GMT
Location: http://localhost:8181/cxf/api/people/ab.com
Server: Jetty(8.1.14.v20131031) 并验证此人已成功创建 curl -i http://localhost:8181/cxf/api/peopleHTTP/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:ab.com,firstName:Tom,lastName:Knocker}] 检查数据库是否也有人填充会很好。 使用Apache Karaf 3.0.1 shell只需执行两个命令即可轻松完成 jdbcdatasources和jdbcquery peopleDb“ select * from people” 。 太棒了 我希望这篇介绍性很强的博客文章能打开另一篇有趣的技术您可以将其用于开发健壮可伸缩模块化和可管理的软件。 我们没有涉及很多东西但是您可以在这里找到它们。 完整的源代码可在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.htmlosgi架构与linux
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/85576.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!