Spring Boot可以让开发者能够更加快速的构建Spring应用。主要提供了如下功能:
创建独立可执行的Spring应用。通过将应用程序打包为jar,就可以通过java -jar来执行应用程序。
内嵌Tomcat, Jetty等WEB服务器,而不需要开发者打包war。
提供starter简化maven依赖关系配置。
将Spring Boot用于微服务开发,可以极大的简化开发者配置和部署。CSE提供了完善的的服务治理能力、良好的跨语言特性和高效的异步通信能力,通过使用CSE,可以快速启用各种满足商业运维需要的功能。基于Spring Boot 2.0的IoT应用集成和使用CSE实践提供了一个实际的例子,描述了Spring Boot中集成CSE框架带来的变化,以及演示 了部分开箱即用的治理功能。CSE同时支持集成Spring Boot 1和Spring Boot 2,在前面的章节中,主要介绍Spring Boot 1,两者集成的原理和步骤基本是一致的,在最后的章节,会描述使用Spring Boot 2的差异。
开发者通常会以如下几种方式使用Spring Boot:
JAVA应用方式:引入spring-boot-starter,开发普通JAVA应用。该应用不会启动WEB服务器。
Web开发方式:引入spring-boot-starter-web,开发Web应用。该应用会包含一个内嵌的Tomcat或者Jetty服务器,并且使用The Spring Web MVC framework(简称Spring MVC)开发REST接口。
在两种情况下,都可以集成CSE,原理图如下:
这种集成方式相对简单,相当于直接将CSE通过Spring Boot应用拉起,不涉及任何改造和变化。
该集成方式的本质是将Spring MVC的DispatcherServlet替换为CSE的RestServlet。
针对Spring Boot、Spring Cloud,提供了如下几个组件:
接入配置中心。当需要在Spring Boot、Spring Cloud应用中,使用配置中心作为动态配置管理工具的时候,需要依赖。
接入服务中心。当需要在Spring Boot、Spring Cloud应用中,使用服务中心作为服务注册、发现管理工具的时候,需要依赖。
适配Spring Cloud的DiscoveryClient接口。当在Spring Cloud中使用@EnableDiscoveryClient时,需要依赖。
在Spring Boot中通过@EnableServiceComb启用CSE的核心功能。这个功能可以用于“JAVA应用方式”和”Web开发方式“。 在”Web开发方式”中,通过spring.main.web-environment=false禁用了Web环境。因此,这个模块主要是解决”JAVA应用方式“的问题。
在Spring Boot中通过@EnableServiceComb启用CSE的核心功能,并启用CSE的RestServlet。用于” Web开发方式“。
开发过程中会使用到的组件是spring-boot-starter-provider和spring-boot-starter-transport,详细使用场景会在后面的章节说明。
使用JAVA方式集成,为Spring Boot应用增加了一个高效的HTTP服务器和REST开发框架。这种方式集成非常简单。只需要在项目中引入相关依赖,并且使用@EnableServiceComb标签即可。
项目代码示例参考:
https://github.com/huawei-microservice-demo/SpringCloudIntegration/blob/master/spring-boot-simple
依赖关系中增加spring-boot-starter-provider,即可引入CSE的核心功能。cse-solution-service-engine增加了接入华为公有云相关的认证模块和治理相关模块,并排除了log4j运行时包,防止和spring boot缺省携带的logback冲突。引入hibernate-validator的目的是spring boot会检测validation-api的实现类,检测不到会无法启动。
com.huawei.paas.cse
cse-dependency
2.3.12
pom
import
org.apache.servicecomb
spring-boot-starter-provider
com.huawei.paas.cse
cse-solution-service-engine
org.slf4j
slf4j-log4j12
org.springframework.boot
spring-boot-starter
org.hibernate
hibernate-validator
在启动类前面增加@EnableServiceComb即可。
@SpringBootApplication
@EnableServiceComb
public class WebsiteMain {
public static void main(final String[] args) {
SpringApplication.run(WebsiteMain.class, args);
}
}
通过以上配置,就可以完整使用CSE提供的所有功能,使用CSE开发REST服务,并开启各种治理功能。
通过microservice.yaml文件可以定制微服务的信息,包括应用名称、微服务名称、监听的地址和端口等。
集成CSE后,可以通过CSE的方式开发REST接口:
@RestSchema(schemaId = "hello")
@RequestMapping(path = "/")
public class HelloService {
@RequestMapping(path = "hello", method = RequestMethod.GET)
public String sayHello(@RequestParam(name="name") String name) {
return "Hello " + name;
}
}
然后可以通过:http://localhost:9093/hello?name=world来访问。
Web开发方式和JAVA应用方式的开发步骤基本类似。示例代码参考:
https://github.com/huawei-microservice-demo/SpringCloudIntegration/blob/master/spring-boot-web
主要有如下区别:
JAVA应用方式基于spring-boot-starter,而Web开发方式基于spring-boot-starter-web。
JAVA应用方式依赖spring-boot-starter-provider,而Web开发方式依赖spring-boot-starter-transport。spring-boot-starter-web已经携带了hibernate-validator,不需要额外依赖。
在启动函数中,Web开发方式可以通过声明
@SpringBootApplication(exclude=DispatcherServletAutoConfiguration.class)
来关闭org.springframework.web.servlet.DispatcherServlet,通过@EnableServiceComb会启用org.apache.servicecomb.transport.rest.servlet.RestServlet。虽然排除DispatcherServlet不是必须的,但是大多数场景一个微服务里面存在多个REST框架都不是很好的主意,会造成很多使用上的误解。
集成CSE后,可以通过CSE的方式开发REST接口:
@RestSchema(schemaId = "hello")
@RequestMapping(path = "/")
public class HelloService {
@RequestMapping(path = "hello", method = RequestMethod.GET)
public String sayHello(@RequestParam(name="name") String name) {
return "Hello " + name;
}
}
然后可以通过:http://localhost:9093/servicecomb/rest/hello?name=world 来访问。其中/servicecomb/rest是配置文件中指定的URI,可以设置为/。
可以看到使用的标签和Spring MVC大部分是一样的。但也有少量不一样的地方,比如:
通过RestSchema替换RestController
需要显示声明@RequestMapping
如果业务代码不是新开发,而是基于Spring MVC做的开发,现在基于CSE做改造,还需要注意在禁用DispatcherServlet后,和其有关的功能特性将不再生效。
在下面的章节,还会详细介绍在Spring MVC模式下两者的区别。
两种开发方式都会启用CSE的全量功能,JAVA应用方式运行于独立的HTTP服务器(基于vert.x构建)上,性能上存在很大的优势。Web开发方式运行于Tomcat或者其他内置的Web服务器之上,作为一个Servlet接收请求,因此在开发过程中,可以使用Web容器提供的一些功能,比如提供页面服务,使用Filter等。当应用只需要提供REST服务,并且对性能要求很高的场景,建议使用JAVA应用方式。
CSE支持使用Spring MVC提供的标签(org.springframework.web.bind.annotation)来声明REST接口,但是两者是独立的实现,而且有不一样的设计目标。CSE的目标是提供跨语言、支持多通信协议的框架,因此去掉了Spring MVC中一些对跨语言支持不是很好的特性,也不支持特定运行框架强相关的特性,比如直接访问Servlet协议定义的HttpServletRequest。下面是一些显著的差别。
Spring MVC使用@RestController声明服务,而CSE使用@RestSchema声明服务,并且需要显示的使用@RequestMapping声明服务路径,以区分该服务是采用Spring MVC的标签还是使用JAX RS的标签。
@RestSchema(schemaId = "hello")
@RequestMapping(path = "/")
Schema是CSE的服务契约,是服务运行时的基础,服务治理、编解码等都基于契约进行。在跨语言的场景,契约也定义了不同语言能够同时理解的部分。
采用Spring MVC,可以在服务定义中使用多种数据类型,只要这种数据类型能够被json序列化和反序列化。比如:
// 抽象类型
public void postData(@RequestBody Object data)
// 接口定义
public void postData(@RequestBody IPerson interfaceData)
// 没指定类型的泛型
public void postData(@RequestBody Map rawData)
// 具体协议相关的类型
public void postData(HttpServletRequest rquest)
上面的类型在CSE都不提供支持。因为CSE会根据接口定义生成契约,从上面的接口定义,如果不结合实际的实现代码或者额外的开发文档说明,无法直接生成契约。也就是站在浏览器的REST视角,不知道如何在body里面构造消息内容。
为了支持快速开发,CSE的数据类型限制也在不停的扩充,比如支持HttpServletRequest,但是实际在使用的时候,他们与WEB服务器的语义是不一样的,比如不能直接操作流。因此建议开发者在CSE的使用场景下,尽可能使用契约能够描述的类型,让代码阅读性更好。
CSE在数据类型的支持方面的更多说明,请参考: https://java.huaweicse.com/build-provider/interface-constraints.html
下面是CSE对于Spring MVC常用标签的支持情况。
标签名称 | 是否支持 | 说明 |
---|---|---|
RequestMapping | 是 | |
GetMapping | 是 | |
PutMapping | 是 | |
PostMapping | 是 | |
DeleteMapping | 是 | |
PatchMapping | 是 | |
RequestParam | 是 | |
CookieValue | 是 | |
PathVariable | 是 | |
RequestHeader | 是 | |
RequestBody | 是 | 目前支持application/json,plain/text |
RequestPart | 是 | 用于文件上传的场景,对应的标签还有Part、MultipartFile |
ResponseBody | 否 | 返回值缺省都是在body返回 |
ResponseStatus | 否 | 可以通过ApiResponse指定返回的错误码 |
RequestAttribute | 否 | Servlet协议相关的标签 |
SessionAttribute | 否 | Servlet协议相关的标签 |
MatrixVariable | 否 | |
ModelAttribute | 否 | |
ControllerAdvice | 否 | |
CrossOrigin | 否 | |
ExceptionHandler | 否 |
|
InitBinder | 否 |
CSE不支持在GET方法中使用POJO对象进行参数映射
比如:public void getOperation(Person p)
CSE不支持在GET方法中使用Map映射所有可能的参数
比如:public void getOperation(Map
说明:需要使用CSE SDK 2.3.51及其以上版本
针对Spring技术体系,CSE提供了如下几个组件,方便开发者。
cse-dependency 这个依赖关系管理器提供CSE推荐的依赖关系管理。它的依赖关系会随着CSE版本的发展进行调整。比如在spring 4是稳定版本的时候,这个管理器提供spring 4的依赖;spring 5是稳定版本的时候,这个管理器提供spring 5的依赖。当前CSE提供的版本默认为spring 4.
cse-dependency-spring4
如果业务代码没使用spring 5或者spring boot 2,可以使用这个管理器。
如果业务代码使用spring 5,可以使用这个管理器。
如果业务代码使用spring boot 1和spring 4,可以使用这个管理器。
如果业务代码使用spring boot 2和spring 5,可以使用这个管理器。
开发者可以利用maven提供的dependencyManagement更好的管理依赖关系。
com.huawei.paas.cse
cse-dependency
${paas.cse.version}
pom
import
CSE 支持spring 4/5 以及spring boot 1/2 maven组件依赖关系配置参考提供了配置和原理说明。
基于Spring Boot 2.0的IoT应用集成和使用CSE实践提供了一个实际Spring Boot 2的例子。
开发者可以通过微服务引擎华为云官网了解CSE。在CSE帮助中心可以获取更多产品信息,如有疑问,可通过CSE论坛进行咨询。