欢迎来到我的博客小站。  交流请加我微信好友: studyjava。  也欢迎关注公众号:Java学习之道 Fork me on GitHub

SpringCloud学习(二):微服务入门实战项目搭建

 

一、开始使用Spring Cloud实战微服务

1、SpringCloud是什么?

云计算的解决方案?不是

SpringCloud是一个在SpringBoot的基础上构建的一个快速构建分布式系统的工具集(全家桶)。

SpringCloud拥有SpringBoot的特点。

2、关于SpringCloud的版本?

  大部分spring软件的版本是以:主版本.次版本.增量版本.里程碑版本的形式命名。

Spring Cloud Angel SR6???

  Angel是SpringCloud的一个大版本,Service Release6版本,标识一个bug修复的版本。

3、SpringCloud的特点?

  1)、约定优于配置

  2)、开箱即用、快速启动

  3)、适用于各种环境(PC Server、云环境、Subtopic、容器Docker)

  4)、轻量级的组件(如服务发现中整合的Eureka)

  5)、组件支持很丰富、功能很齐全(如提供配置中心、注册中心、智能路由…)

  6)、选型中立(服务发现中使用Eureka、Zookeeper、Consul等都可以)

二、需要的技术储备

  1、java(scala、Groovy…均可)

  2、构建工具

    1)、Maven

    2)、Gradle

      将maven项目转换成gradle项目:(在pom文件的上一级目录执行如下命令,使用cmd操作)

      gradle init --type pom

    3)、SpringBoot:http://cnblogs.com/mmzs/category/1192166.html

三、使用的软件版本

  1、原则:使用最新的版本进行讲解

  2、JDK 1.8

  3、Maven 3.3.9

  4、IDE(Spring Tool Suite 3.8.2、IDEA、Eclipse)

  5、Spring Boot

  6、SpringCloud Camden SR1

建议:大家学习时,尽量使用相同的版本进行选择,避免采坑

SpringCloud学习(二):开始使用Spring Cloud实战微服务

四、创建工程

1、创建调用关系的微服务

创建存在调用关系的微服务,调用关系如下

服务消费者:服务的调用方,调用别的微服务的微服务(即:依赖其他服务的服务)

服务提供者:服务的被调用方,提供API的微服务(即:为其他服务提供服务的服务)

2、编写一个服务提供者

登陆:http://start.spring.io/

填写信息:

(1)、将生成的maven工程导入eclipse

然后一次创建如下选中的类和配置文件。

(2)、data.sql和schema.sql

insert into user(id,username, name, age, balance) values(1,'liubei', '刘备', 20, 100.00);
insert into user(id,username, name, age, balance) values(2,'guanyu', '关羽', 20, 100.00);
insert into user(id,username, name, age, balance) values(3,'zhangfei', '张飞', 20, 100.00);
insert into user(id,username, name, age, balance) values(4,'machao', '马超', 20, 100.00);
data.sql
drop table user if exists;
create table user(
    id bigint generated by default as identity,
    username varchar(40),
    name varchar(20),
    age int(3),
    balance decimal(10,2), 
    primary key(id)
);
schema.sql

(3)、配置文件application.yml

 1 server:
 2   # 服务器端口号
 3   port: 6900
 4 spring:
 5   jpa:
 6     # 是否生成ddl语句
 7     generate-ddl: false
 8     # 是否打印sql语句
 9     show-sql: true
10     hibernate:
11       # 自动生成ddl,由于指定了具体的ddl,此处设置为none
12       ddl-auto: none
13   datasource:
14     # 使用H2数据库
15     platform: h2
16     # 指定生成数据库的schema文件位置
17     schema: classpath:schema.sql
18     # 指定插入数据库语句的脚本位置
19     data: classpath:data.sql
20     
21 # 配置日志打印信息    
22 logging:
23   level:
24     root: INFO
25     org.hibernate: INFO
26     org.hibernate.type.descriptor.sql.BasicBinder: TRACE
27     org.hibernate.type.descriptor.sql.BasicExtractor: TRACE
28     com.itmuch: DEBUG
schema.sql

(4)、创建UserController

 1 package com.mmzs.cloud.controller;
 2 
 3 import javax.annotation.Resource;
 4 import javax.websocket.server.PathParam;
 5 
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.web.bind.annotation.GetMapping;
 8 import org.springframework.web.bind.annotation.PathVariable;
 9 import org.springframework.web.bind.annotation.RequestMapping;
10 import org.springframework.web.bind.annotation.RestController;
11 
12 import com.mmzs.cloud.UserRepository;
13 import com.mmzs.cloud.entity.User;
14 
15 /**
16  * @author: mmzsit
17  * @date:   2018年8月17日
18  * @Description: 
19  * 博客地址:https://www.cnblogs.com/mmzs/p/9282412.html
20  * @version V1.0
21 */
22 @RestController
23 public class UserController {
24     
25     @Resource
26     private UserRepository userRepository;
27     
28     //第一种方式
29     @GetMapping("/user/{id}")
30     //第二种方式
31     //@RequestMapping(value="/xxx",method=org.springframework.web.bind.annotation.RequestMethod.GET)
32     //第一种和第二种方式其实是等效的
33     public User findById(@PathVariable Long id){
34         return this.userRepository.getOne(id);
35     }
36 }
UserController

(5)、创建UserRepository

 1 package com.mmzs.cloud;
 2 
 3 
 4 import org.springframework.data.jpa.repository.JpaRepository;
 5 import org.springframework.stereotype.Repository;
 6 
 7 import com.mmzs.cloud.entity.User;
 8 
 9 /**
10  * @author: mmzsit
11  * @date:   2018年8月17日
12  * @Description: 
13  * 博客地址:https://www.cnblogs.com/mmzs/p/9282412.html
14  * @version V1.0
15 */
16 @Repository
17 public interface UserRepository extends JpaRepository<User, Long>{
18 
19     /**
20      * @Description: 
21      * @param:  @param id
22      * @param:  @return
23      * @return: User
24      * @throws
25     */
26 //    User findOne(Long id);
27 
28     
29 
30 }
UserRepository

(6)、创建实体类User

 1 package com.mmzs.cloud.entity;
 2 
 3 import java.math.BigDecimal;
 4 
 5 import javax.persistence.Column;
 6 import javax.persistence.Entity;
 7 import javax.persistence.GeneratedValue;
 8 import javax.persistence.GenerationType;
 9 import javax.persistence.Id;
10 
11 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
12 
13 /**
14  * @author: mmzsit
15  * @date:   2018年8月17日
16  * @Description: 
17  * 博客地址:https://www.cnblogs.com/mmzs/p/9282412.html
18  * @version V1.0
19 */
20 @Entity
21 @JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" })
22 public class User {
23     
24     @SuppressWarnings("unused")
25     private static final long serialVersionUID = 1L;
26     
27     @Id
28     @GeneratedValue(strategy=GenerationType.AUTO)
29     private Long id;
30     @Column
31     private String username;
32     @Column
33     private String name;
34     @Column
35     private Short age;
36     @Column
37     private BigDecimal balance;
38     
39     public Long getId() {
40         return id;
41     }
42     public String getUsername() {
43         return username;
44     }
45     public String getName() {
46         return name;
47     }
48     public Short getAge() {
49         return age;
50     }
51     public BigDecimal getBalance() {
52         return balance;
53     }
54     public void setId(Long id) {
55         this.id = id;
56     }
57     public void setUsername(String username) {
58         this.username = username;
59     }
60     public void setName(String name) {
61         this.name = name;
62     }
63     public void setAge(Short age) {
64         this.age = age;
65     }
66     public void setBalance(BigDecimal balance) {
67         this.balance = balance;
68     }
69     
70 }
User

注:此处采用的是jpa,使用的是h2数据库,如果访问时出现实体类转化json格式错误,则需要在实体类前面加上如下这句注释:

@JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" })

错误提示:disable SerializationFeature.FAIL_ON_EMPTY_BEANS

(7)、执行MicroserviceSimpleProviderUserApplication类,然后进行访问测试

 

3、编写一个服务消费者

登陆:http://start.spring.io/

填写信息:

(1)、将生成的maven工程导入eclipse

然后一次创建如下选中的类和配置文件。

(2)、配置文件application.yml

server:
  port: 6901

(3)、创建GoodsController

 1 package com.mmzs.cloud.controller;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.beans.factory.annotation.Value;
 5 import org.springframework.web.bind.annotation.GetMapping;
 6 import org.springframework.web.bind.annotation.PathVariable;
 7 import org.springframework.web.bind.annotation.RestController;
 8 import org.springframework.web.client.RestTemplate;
 9 
10 import com.mmzs.cloud.entity.User;
11 
12 /**
13  * @author: mmzsit
14  * @date: 2018年8月17日
15  * @Description: 博客地址:https://www.cnblogs.com/mmzs/p/9282412.html
16  * @version V1.0
17  */
18 @RestController
19 public class GoodsController {
20     @Autowired
21     private RestTemplate restTemplate;
22 
23     @GetMapping("/goods/{id}")
24     public User findById(@PathVariable Long id) {
25         //采用了硬编码注册user服务
26         return this.restTemplate.getForObject("http://localhost:6900/user/" + id, User.class);
27     }
28 }
GoodsController

(4)、创建实体类User

 1 package com.mmzs.cloud.entity;
 2 
 3 import java.io.Serializable;
 4 import java.math.BigDecimal;
 5 
 6 /**
 7  * @author: mmzsit
 8  * @date:   2018年8月17日
 9  * @Description: 
10  * 博客地址:https://www.cnblogs.com/mmzs/p/9282412.html
11  * @version V1.0
12 */
13 
14 public class User implements Serializable{
15     
16     private static final long serialVersionUID = -7125209803403015533L;
17     
18     private Long id;
19     private String username;
20     private String name;
21     private Short age;
22     private BigDecimal balance;
23     public Long getId() {
24         return id;
25     }
26     public void setId(Long id) {
27         this.id = id;
28     }
29     public String getUsername() {
30         return username;
31     }
32     public void setUsername(String username) {
33         this.username = username;
34     }
35     public String getName() {
36         return name;
37     }
38     public void setName(String name) {
39         this.name = name;
40     }
41     public Short getAge() {
42         return age;
43     }
44     public void setAge(Short age) {
45         this.age = age;
46     }
47     public BigDecimal getBalance() {
48         return balance;
49     }
50     public void setBalance(BigDecimal balance) {
51         this.balance = balance;
52     }
53     
54 }
User

(5)、在MicroserviceSimpleConsumerGoodsApplication类中注入Bean

 其中11-16行表示注入的Bean

 1 package com.mmzs.cloud;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.context.annotation.Bean;
 6 import org.springframework.web.client.RestTemplate;
 7 
 8 @SpringBootApplication
 9 public class MicroserviceSimpleConsumerGoodsApplication {
10     
11     @Bean
12     public RestTemplate restTemplate() {
13         return new RestTemplate();
14     }
15     //12、13、14、行相当于16行
16     //private RestTemplate restTemplate = new RestTemplate();
17 
18     public static void main(String[] args) {
19         SpringApplication.run(MicroserviceSimpleConsumerGoodsApplication.class, args);
20     }
21 }
MicroserviceSimpleConsumerGoodsApplication

(5)、执行MicroserviceSimpleConsumerGoodsApplication类,然后进行访问测试

4、小小优化一下

主要优化的点是在GoodsController类中的硬编码部分。简单优化如下:

@RestController
public class GoodsController {
    @Autowired
    private RestTemplate restTemplate;

    //优化部分
    @Value("${user.userServicePath}")
    private String userServicePath; 
    
    //优化后此处的硬编码字符串,修改为变量获取
    @GetMapping("/goods/{id}")
    public User findById(@PathVariable Long id) {
        //采用了硬编码注册user服务
        return this.restTemplate.getForObject(this.userServicePath + id, User.class);
    }
}

这样子的话,userServicePath的具体值需要通过配置文件application.yml来配置,故application.yml文件修改为:

server:
  port: 6901
# 优化部分
user:
  userServicePath: http://localhost:6900/user/

注: 其实这样子的优化也不是很好,因为当微服务过多时,层层调用,需要修改的部分也会越来越多,不便于维护和修改。具体措施,详见下回分解。

五、代码下载

点击这里跳转

如果需要积分的话,其实大家没必要消耗积分进行下载,按照文章内容一步一步来,绝对是可以完美测试成功的,动手过程,让影响更加深刻,不是吗? 

posted @ 2018-08-30 10:09  淼淼之森  阅读(22365)  评论(5编辑  收藏  举报
  👉转载请注明出处和署名