0
点赞
收藏
分享

微信扫一扫

Spring Cloud微服务实战---1.1.配置开发环境


随着应用系统的功能越来越复杂,应用系统的复杂度也越来越大,传统的基于单体应用模式,在实践中遇到了非常大的问题,微服务架构在此背景下应运而生。由于微服务架构还比较新,对开发团队的要求非常高,所以实际中还没有得到广泛的应用。而随着Spring Cloud的推出和成熟,集成了微服务架构所需的服务,大大降低了微服务采用门槛。本系列文章将向大家详细介绍采用Spring Cloud进行微服务应用系统开发的技术。

创建微服务

我们首先到Spring网站创建一个新应用:​​https://start.spring.io/,如下所示:​​

Spring Cloud微服务实战---1.1.配置开发环境_微服务

我们输入Group为包名,Artifact为项目名,然后选择依赖库:Web、JPA、H2、Lombok,其他版本使用缺省值即可,点击 Generate Project,其会自动生成并下载micro_service_demo.zip文件,就是为我们生成好的工程。

将该文件解压后,可以得到如下目录内容:

Spring Cloud微服务实战---1.1.配置开发环境_Spring Boot_02


我们在这里使用Spring出品的Spring Tool Suite来进行开发,打开STS,引入现有的MVN工程,成功后如下所示:

Spring Cloud微服务实战---1.1.配置开发环境_Spring Boot_03


我们首先需要在STS中安装 lombok库,该库使可以使我们直接写log,并且自动替我们生成get和set方法。从网址:​​https://projectlombok.org/下载lombok.jar文件,然后将lombok.jar拷贝到STS根目录下(有sts.ini文件的目录),在该目录下打开命令窗口,运行如下命令:​​

java -jar lombok.jar

按照提示信息安装即可。安装完成后,重启STS即可。
假设我们需要维护商品信息,包括商品名称、图片URL、商品类别编号、价格、数量信息,我们先将这些信息保存在内存数据库H2,使用JPA(Java Persistent API)来对数据进行增删改查操作。
Spring采用领域驱动开发(DDD)模式,所以在缺省情况下,使用JPA来进行数据库操作。很多朋友可能在实际应用中,使用MyBatis会更多一些,因为MyBatis对于使用SQL来操作关系数据库会更灵活一些,而JPA以及其底层的Hibernate是一个相对重量级的ORM框架,使用OO方式来操作数据库(虽然也可以使用SQL,但是不是其强项)。我们在实际项目经常采用如下方式:使用JPA进行领域建模,完成数据库增删改操作,而查询操作直接采用JDBC来进行。
我们先来建立产品实体类:

package com.wkyai.mse.product;

import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Data
@Entity
public class Product {
private @Id @GeneratedValue Long productId;
private String productName;
private String imageUrl;
private double price;
private int quantity;

Product(String productName, String imageUrl, double price, int quantity) {
this.productName = productName;
this.imageUrl = imageUrl;
this.price = price;
this.quantity = quantity;
}
......

}

第8行:@data注解是我们在创建项目时添加的依赖库Lombok用来生成一些类的基本功能的注解,如为属性生成get和set方法,生成java类所需要的equals、hash、toString方法;
第9行:@Entity注解是告诉JPA,这个类对应数据库中的一个表;
第11行:定义表的主键为productId,类型为long型,具有自增特性;
第12~15行:定义产品表的其他属性,每个属性对应数据库表的一个字段;
第17~22行:定义构造函数;
为了让JPA来为我们生成数据库表的增删改查操作,我们还需要定义如下类:

package com.wkyai.mse.product;

import org.springframework.data.jpa.repository.JpaRepository;

public interface ProductRepository extends JpaRepository<Product, Long>{
}

经过上面的步骤,就可以让JPA来替我们完成数据库表的增删改查操作了。
接下来我们需要先向H2数据库中插入几条数据,为了达到这个目的,我们需要在系统启动时运行我们的代码,我们可以通过Spring Boot的Configure来实现,如下所示:

@Configuration
@Slf4j
public class DatabaseInitializer {
@Bean
CommandLineRunner initializeDatabase(ProductRepository repository) {
return args -> {
repository.save(new Product("P001", "img1.jpg", 1.0, 100));
repository.save(new Product("P002", "img2.jpg", 2.0, 102));
Logger log = LoggerFactory.getLogger("aaa");
log.info("启动程序时运行的代码运行了");
};
}
}

下面我们编写REST服务:

@RestController
public class ProductController {
private final ProductRepository repository;

public ProductController(ProductRepository repository) {
this.repository = repository;
}

@GetMapping("/products")
public List<Product> all() {
return repository.findAll();
}
}

我们在MseApplication.java中,在main方法定义处中点击右键,选择运行为Spring Boot,会打印如下信息:

Spring Cloud微服务实战---1.1.配置开发环境_JPA_04


从上图可以看到,我们在DatabaseInitializer中打印的信息已经打印出来了,证明我们数据库已经初始化完成,并且知道服务启动在8080端口。打开浏览器访问如下地址:​​http://localhost:8080/products,并显示如下信息:​

Spring Cloud微服务实战---1.1.配置开发环境_JPA_05


从这里可以看出,我们在启动时加到数据库中的信息,已经成功打印出来了。这里我们只做了一个全部产品的查询功能,下面我们实现单个产品的查询功能,在ProductController类中添加如下代码:

@GetMapping("/products/{productId}")
public Product one(@PathVariable Long productId) {
return repository.findById(productId).orElseThrow( () -> new ProductNotFoundException(productId) );
}

当查询不到产品时,会报404错误,我们就抛出一个异常,定义如下所示:

public class ProductNotFoundException extends RuntimeException {
public ProductNotFoundException(Long id) {
super("产品编号:" + id + "!");
}
}

接下来我们定义这个异常的处理类:

@ControllerAdvice
public class ProductNotFoundAdvice {
@ResponseBody
@ExceptionHandler(ProductNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
HttpErrorResponse productNotFoundHandler(ProductNotFoundException ex) {
HttpErrorResponse json = new HttpErrorResponse(1, "查询产品失败", ex.getMessage());
return json;
}
}

定义一个统一的HTTP失败的响应类,如下所示:

import lombok.Data;

@Data
public class HttpErrorResponse {
private long status;
private String message;
private String reason;

public HttpErrorResponse() {
status = 0L;
message = "Ok";
reason = "ok";
}

public HttpErrorResponse(long status, String message, String reason) {
this.status = status;
this.message = message;
this.reason = reason;
}
}

下面我们来看怎样添加产品,如下所示:

@PostMapping("/products")
public Product newProduct(@RequestBody Product newProduct) {
return repository.save(newProduct);
}

为了能测试添加产品功能,我们需要发送HTTP的POST、PUT和DELETE请求,我们需要下载一个接口开发调试工具postman:​​https://dl.pstmn.io/download/latest/win64,安装完成之后,界面如下所示:​​

Spring Cloud微服务实战---1.1.配置开发环境_JPA_06


Spring Cloud微服务实战---1.1.配置开发环境_Spring Boot_07


如上图所示,配置完成后点击发送按钮,会显示如下结果:

Spring Cloud微服务实战---1.1.配置开发环境_Spring Boot_08


上图的下部就是发送这个请求后的响应,由图中可以看到,在响应中成功返回了新加入产品的productId,通过前面的查询接口,也可以正确显示出新添加的产品,这表明我们添加产品的功能已经成功完成了。

接下来我们来看产品信息的修改,假设我们需要修改prodctId=2的产品,将产品名改为“商品2”,这时我们就需要使用PUT请求,如下所示:

@PutMapping("/products/{productId}")
public Product updateProduct(@RequestBody Product product, @PathVariable long productId) {
return repository.findById(productId).
map(item -> {
item.setProductName(product.getProductName());
item.setImageUrl(product.getImageUrl());
item.setPrice(product.getPrice());
item.setQuantity(product.getQuantity());
return repository.save(item);
}).orElseGet(() -> {
product.setProductId(productId);
return repository.save(product);
} );
}

我们在postman上定义一个PUT请求,如下所示:

Spring Cloud微服务实战---1.1.配置开发环境_Spring Boot_09


最后我们来看删除操作,如下所示:

@DeleteMapping("/products/{productId}")
public Product deleteProduct(@PathVariable long productId) {
Product product = repository.findById(productId).get();
repository.deleteById(productId);
return product;
}

我们在postman里设置DELETE请求,如下所示:

Spring Cloud微服务实战---1.1.配置开发环境_Spring_10


通过前面的查询接口,可以验证我们确实已经删除了指定记录。

截止目前为止,我们已经实现了一个简单的Spring Boot服务。我们知道,现在使用Http的场合越来越少,像苹果等厂家已经强制大家转向HTTPS,所以在下一节中,我们将使我们的服务使用HTTPS协议。


举报

相关推荐

0 条评论