01 SpringCloud 初级部分


尚硅谷周阳老师的SpringCloud

将目前学习的笔记整理,方便自己复习,若有不足,还请指正。

Cloud各种组件的停更/升级/替换

SpringCloud=分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体,俗称微服务全家桶

SpringBoot是一种服务开发技术

服务注册与发现:EUREKA

服务负载均衡与调用:NETFLIX OSS RIBBON

服务负载与调用:NETTFLIX

服务熔断降级:HYSTRIX

服务网关:Zuul

服务分布式配置:SpringCloud Config

服务开发:SpingBoot

SpringBoot 2.0版和SpringCloud H版 强烈建议使用SpringBoot 2.0以上

在 SpringCloud 官网 点击 LEARN 可以看到最新的 SpringCloud 再点击 Reference.Doc 可以看到 Sprng Cloud 对应的 Boot 版本

父工程的POM

删除src目录,并在pom中添加

pom

然后把pom下的都用下面这些替换了。

 
  
    UTF-8
    1.8
    1.8
    4.12
    1.2.17
    1.16.18
    5.1.47
    1.1.16
    1.3.0
  

  
  
  
  
    
      
      
        org.springframework.boot
        spring-boot-dependencies
        2.2.2.RELEASE
        pom
        import
      
      
      
        org.springframework.cloud
        spring-cloud-dependencies
        Hoxton.SR1
        pom
        import
      
      
      
        com.alibaba.cloud
        spring-cloud-alibaba-dependencies
        2.1.0.RELEASE
        pom
        import
      

      
        mysql
        mysql-connector-java
        ${mysql.version}
      
      
        com.alibaba
        druid
        ${druid.version}
      
      
        org.mybatis.spring.boot
        mybatis-spring-boot-starter
        ${mybatis.spring.boot.version}
      
      
        junit
        junit
        ${junit.version}
      
      
        log4j
        log4j
        ${log4j.version}
      
      
        org.projectlombok
        lombok
        ${lombok.version}
        true
      
    
  

  
    
      
        org.springframework.boot
        spring-boot-maven-plugin
        
          true
          true
        
      
    
  


maven中dependencyManagement标签:

使用dependencyManagement 标签 可以让所有子项目引用一个依赖而不用显示的列出Maven,Maven会沿着父子层次向上走,直到找到一个dependencyManagement 的项目

子项目中,如果不指定版本号,默认和父项目dependencyManagement标签中的版本一致,并且父项目dependencyManagement标签只是规定了版本号,具体引入依赖还是子项目引入。

这样可以避免在每个使用的子项目里都声明一个版本号,当升级或切换到另一个版本时,只需要在顶层父 里更新就行

支付模块

订单(端口号:80)模块调用 支付模块(端口号:8001)

步骤:

  1. 建module
  2. 改pom
  3. 写yml
  4. 主启动
  5. 业务类
  6. 测试

新建一个 module

子项目名:cloud-provider-payment8001

父类的pom 中出现 一个modules 标签

  
    cloud-provider-payment8001
  

在子类pom中添加依赖


        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
        
        
            com.alibaba
            druid-spring-boot-starter
            1.1.20
            
        
        
        
            mysql
            mysql-connector-java
        
        
        
            org.springframework.boot
            spring-boot-starter-jdbc
        
        
        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

在 resources 目录下 创建 application.yml 文件

#微服务建议一定要写服务端口号和微服务名称
server:
  port: 8001

spring:
  application:
    #微服务名称
    name: Cloud-payment-service
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    #mysql5.x的没有cj
    driver-class-name: com.mysql.jdbc.Driver
    #记得先创建数据库
    url: jdbc:mysql://localhost:3306/db2020?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456

#mybatis配置
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.angenin.springcloud.entities  #所有Entity别名类所在包


业务类

1. 建表

CREATE TABLE `payment`(
	`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
	`serial` VARCHAR(200) DEFAULT '',
	PRIMARY KEY(`id`)
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

INSERT INTO payment(`serial`)VALUES("张三");

2. entities 层

实体类包

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Payment {

    private Long id;
    private String serial;
}

entities包下新建CommonResult(json封装体,传给前端的)

@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonResult {

    private Integer code;
    private String message;
    private T      data;

    ////自定义两个参数的构造方法
    public CommonResult(Integer code,String message){
        this(code,message,null);
    }
}

3.dao 层

@Mapper
public interface PaymentDao {

    public int create(Payment payment);

    public Payment getPaymentById(Long id);
}

在 resources 下 新建mapper目录,然后新建PaymentMapper.xml

在配置文件中有 对 mapper 的配置

<?xml version="1.0" encoding="UTF-8" ?>





    
        insert into payment(serial) values(#{serial});
    


    
        
        
    

    


4. service 层

public interface PaymentService {
    public int create(Payment payment);

    public Payment getPaymentById(Long id);
}

在service包下新建impl.PaymentServiceIpml实现类

@Service
public class PaymentServiceImpl implements PaymentService {

    @Resource //java自带的  @Autowired 一样
    private PaymentDao paymentDao;

    @Override
    public int create(Payment payment) {
        return paymentDao.create(payment);
    }

    @Override
    public Payment getPaymentById(Long id) {
        return paymentDao.getPaymentById(id);
    }
}

5. controller层

@RestController
@Slf4j
public class PaymentController {

    @Resource
    private PaymentService paymentService;

    @PostMapping("/payment/create")
    public CommonResult create(Payment payment){
        int result = paymentService.create(payment);
        log.info("插入结果"+result);
        if (result > 0){
            return new CommonResult(200,"插入数据库成功",result);
        }else {
            return new CommonResult(444,"插入数据库失败",null);
        }
    }

    @GetMapping ("/payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id")Long id){
        Payment payment = paymentService.getPaymentById(id);

        log.info("插入结果"+payment);
        if (payment != null){
            return new CommonResult(200,"查询成功",payment);
        }else {
            return new CommonResult(444,"查询失败,查询ID:"+id,null);
        }
    }
}

消费者订单模块

  1. 新建一个module 名字:cloud-consumer-order80

  2. 改pom文件

  3. yml文件

    加上端口

    server:
      port: 80
    
  4. 主启动

  5. 写业务

消费者不需要与数据库进行操作

复制cloud-provider-payment8001项目里的entities(里面2个实体类)到本项目(cloud-consumer-order80)的springcloud包下。

使用 RestTemplate

@Configuration
public class ApplicationContextConfig {

    //往容器中添加一个RestTemplate
    //RestTemplate提供了多种便捷访问远程http访问的方法
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

controller层

@RestController
@Slf4j
public class OrderController {

    public static final String PAYMENT_URL = "http://localhost:8001";

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/payment/create")
    public CommonResult create(Payment payment){
        // //postForObject分别有三个参数:请求地址,请求参数,返回的对象类型
        return restTemplate.postForObject(PAYMENT_URL + "/payment/create", payment, CommonResult.class);
    }

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult getPayment(@PathVariable("id")Long id){
        return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    }
}

idea 启动两个服务时 会放到 Services中

如果没有services view---> Tool Windows--->services 开启 在services中 add

消费者不需要知道 端口不用加

测试:http://localhost/consumer/payment/get/11

http://localhost/consumer/payment/create?serial=123 插入一条数据。

工程重构

系统中的 entities包中的类相同,把相似的部分拿出

1.新建 module:cloud-api-commons

2. pom加入依赖

    
        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
            org.projectlombok
            lombok
            true
        
        
        
            cn.hutool
            hutool-all
            5.1.0
        
    

3. 拷贝entities到本项目中(路径需要一样,先在本项目中建包,然后在拷贝)

4. 对本项目进行打包

先清理 再打包

maven通过install将本地工程打包成jar包,放入到本地仓库中,再通过pom.xml配置依赖引入到当前工程。

  1. 删除另外两个项目的entities包

  2. 在两个项目中的pom文件中引入依赖

       
           com.atguigu.springcloud
           cloud-api-commons
           ${project.version}