Spring Boot学习(三)

开发微服务

Boot对Spring应用的开发进行了简化,提供了模块化方式导入依赖的能力,强调了开发RESTful Web服务的功能并提供了生成可运行jar的能力,这一切都清晰地表明在开发可部署的微服务方面Boot框架是一个强大的工具。正如前面的例子所示,借助于Boot,让一个RESTful Web工程运行起来是一件很容易的事情;不过,为了了解Boot所有潜在的功能,我们会阐述在开发完整功能的微服务时,会遇到的所有繁琐的事情。在企业级基础设施领域,微服务是一种越来越流行的应用架构,因为它能够实现快速开发、更小的代码库、企业级集成以及模块化部署。有众多的框架致力于该领域的开发,该章节将会讨论使用Boot如何简化这一过程。

数据访问

我们可以基于各种目的来构建微服务,但有一点是肯定的,那就是大多数都需要读取和写入数据库的能力。Spring Boot使数据库集成变成了一项非常简单的任务,因为它具有自动配置Spring Data以访问数据库的能力。只需在你的工程中将spring-boot-starter-data-jpa包含进来,Boot的自动配置引擎就能探测到你的工程需要数据访问功能,并且会在Spring应用上下文中创建必要的Bean,这样你就可以使用Repository和服务了。为了更具体地阐述这一点,请参见程序清单1.4中的Gradle构建文件,它列出了一个基于Groovy的微服务web应用的构建结构,该应用使用了Spring Data对JPA的支持来实现数据访问。

程序清单1.4

buildscript {
  repositories {
    maven { url"http://repo.spring.io/libs-snapshot" }
    mavenCentral()
  }
  dependencies {
   classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.0.RC1")
  }
}
 
apply plugin: 'groovy'
apply plugin: 'spring-boot'
 
repositories {
  mavenCentral()
  maven { url"http://repo.spring.io/libs-snapshot" }
}
 
ext {
  springBootVersion= "1.0.0.RC1"
}
 
dependencies {
  compile'org.codehaus.groovy:groovy-all:2.2.1'
  compile"org.springframework.boot:spring-boot-starter-web:$springBootVersion"
  compile"org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
  compile"org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
}

在这个配置中,Boot的actuator模块提供了对hsqldb的依赖,这会搭建所有必要的依赖——包括模式的创建——因此Spring Data可以使用这个内存数据库作为数据源。这种简便的方式能够让开发人员免于在开发期创建和管理复杂的XML配置,进而能够快速地开发数据库驱动的微服务。如果在classpath中有H2或Derby数据库的话,这种自动化配置也会生效。Boot所提供的另一个便利之处就是能够快速简便地使用相关数据启动应用的数据库模式。这在开发期是非常有用的,此时数据库可能是在内存中或者是不稳定的,开发人员需要保证的是在应用启动的时候能够访问到这些特定的数据。为了阐述这一点,考虑一下程序清单1.5中的示例JPA实体,它代表了微服务所提供的“User”数据结构。

程序清单1.5

@Entity
class User {
  @Id
  @GeneratedValue
  Long id
 
  String username
  String firstName
  String lastName
  Date createdDate
  Date lastAccessed
 
  Boolean isActive= Boolean.TRUE
}

为了启用代表User对象的通用数据,我们只需创建一个名为schema.sql或data.sql的文件,并将其包含在classpath之中。这个文件会在模式创建完成之后执行,所以基于程序清单1.5所给出的实体,我们可以使用SQL语句启用一个用户账号,如程序清单1.6所示。

程序清单1.6

insert into user(username, first_name, last_name,created_date) values ('danveloper', 'Dan', 'Woods', now())

在启动的时候,我们所提供的SQL代码会执行,这样就能确保有一个测试账号可以使用。微服务此时已经具有了数据访问的起始点,程序清单1.7展现了如何按照Spring Data的开发模式创建Repository接口,该接口会作为User实体的数据访问对象(Data Access Object)。

程序清单1.7

public interface UserRepository extendsCrudRepository<User, Long> {
}

CrudRepository提供了一些通用的接口方法来创建、查询、更新以及删除对象和对象集合。应用所需的其他特定功能可以按照Spring Data的Repository开发约定进行定义。一旦UserRepository接口创建成功,Boot的spring-data-jpa层会在工程中探测到它,并将其添加到Spring应用上下文之中,这样对于controller和sevice对象来说,它就成为可以进行自动注入的可选对象。这种自动化的配置只有在Boot应用要求按照这种方式初始化的时候才生效,这是通过存在@EnableAutoConfiguration注解来标识的。借助程序清单1.8中所实现的controller,微服务现在就可以定义RESTful端点了,服务的使用者可以获取到User的列表或单个User。

程序清单1.8

@RestController
@EnableAutoConfiguration
@RequestMapping("/user")
class UserController {
 
  @Autowired
  UserRepositoryrepository
 
 @RequestMapping(method=[RequestMethod.GET])
  def get(Long id){
    id ?repository.findOne(id) : repository.findAll()
  }
 
  public staticvoid main(String[] args) {
   SpringApplication.run UserController, args
  }
}

在启动的时候,应用将会输出日志,表明Hibernate按照User实体的定义创建数据库结构,在应用初始化的最后,Boot还会从schema.sql文件中导入数据。

在开发微服务应用时,需要特别注意的一点是使用了@RequestMapping注解。这不是Boot特定的注解。不过,因为Boot安装了自己的端点以监控应用的性能、健康情况以及配置,所以需要确保应用的代码不要与这些内置的提供详情的路径解析相冲突。鉴于此,如果有从请求路径中解析属性的需求(在我们的场景中,也就是user的id属性),那么我们需要仔细考虑这个动态的属性解析会对微服务的其他行为产生什么影响。在本例中,只是简单地将controller映射到/user端点而不是根上下文,就能允许Boot的端点也可以进行访问。

微服务所提供的数据并不一定全部适合关系型结构,针对这一点Spring Boot也暴露了一些模块,从而让开发人员可以使用Spring Data的MongoDB和Redis项目,不过依然采取特定的方式来进行配置。Spring Data用来定义数据访问对象(Data Access Object)的高层框架,这样快速切换JPA与非JPA数据源会变得非常容易。参见程序清单1.9,它展现了一个重新定义的UserRepository接口,这个接口设计为使用MongoDB取代JPA。

程序清单1.9

public interface UserRepository extendsMongoRepository<User, Long> {
}
MongoRepository接口也扩展了CrudRepository,因此微服务的Controller代码,也就是程序清单1.8所示并不需要修改。为了实现与MongoDB的集成,工程唯一要做的就是在应用的classpath中包含spring-boot-starter-data-mongodb。程序清单1.4所示的Gradle构建文件需要稍微调整一下依赖的部分,如程序清单1.10所示。

程序清单1.10

dependencies {
  compile'org.codehaus.groovy:groovy-all:2.2.1'
  compile"org.springframework.boot:spring-boot-starter-web:$springBootVersion"
  compile"org.springframework.boot:spring-boot-starter-data-mongodb:$springBootVersion"
  compile"org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
}

MongoDB依赖都置于classpath之中以后,Boot将会自动配置Spring Data连接到localhost上的数据库,并且默认的数据库名为test。在这个库中,将会自动创建User集合(按照MongoDB的标准),微服务现在就能使用MongoDB作为后端了。对非JPA的数据存储来说,初始化数据比其他的方式更为简单,这主要是因为它不能针对MongoDB的文档存储和Redis的键值存储运行SQL文件。鉴于Spring Data会使用这些存储的持久化实例,这就意味着开发期创建的数据需要在重启后保留。为了持久化数据,我们需要修改微服务的controller,这样服务的使用者就能创建User实例了。我们也可以将微服务的UserController进行修改,使其符合通用的RESTful API结构,让controller以不同的方式处理不同的HTTP方法。程序清单1.11展现了为controller添加创建新User实例的功能。

程序清单1.11

@RestController
@RequestMapping("/user")
@EnableAutoConfiguration
class UserController {
 
  @Autowired
  UserRepositoryrepository
 
 @RequestMapping(method=[RequestMethod.GET])
  def get(Long id){
    id ?repository.findOne(id) : repository.findAll()
  }
 
 @RequestMapping(method=[RequestMethod.POST])
  defcreate(@RequestBody User user) {
    repository.saveuser
    user
  }
 
  public staticvoid main(String[] args) {
   SpringApplication.run UserController, args
  }
}

当微服务的使用者往应用的端点上发送一个HTTP POST请求时,Spring将会把请求体转换为User实例。代码接下来会使用UserRepository将这个对象存储到MongoDB集合之中。使用curl创建User实例的样例如程序清单1.12所示。

程序清单1.12

curl -v -H "Content-Type: application/json" -d"{ \"username\": \"danveloper\",\"firstName\": \"Dan\", \"lastName\":\"Woods\", \"createdDate\": \"2014-02-02T00:00:00\"}" http://localhost:8080/user

按照Boot针对Mongo数据源的特定配置,新的User实例默认会持久化到本地Mongo实例的test数据库的user集合之中。如果我们打开web浏览器并对微服务发起一个HTTP GET请求,我们就能看到所创建的user存在于返回的列表之中。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值