• # 从浅入深 学习 SpringCloud 微服务架构(六)Feign(1)


    从浅入深 学习 SpringCloud 微服务架构(六)Feign(1)

    一、Feign 组件概述:

    Feign 是 Netflix 开发的声明式,模板化的HTTP客户端。
    其灵感来自 Retrofit,JAXRS-2.0 以及 WebSocket。

    Feign 可帮助我们更加便捷,优雅的调用 HTTP[API。

    在 SpringCloud 中,使用 Feign 非常简单,
    在项目中创建一个接口,并在接口上添加一些注解,代码就完成了。

    Feign 支持多种注解,例如 Feign 自带的注解或者JAX-RS注解等。

    SpringCloud 对 Feign 进行了增强,使 Feign 支持了 SpringMVC 注解,
    并整合了 Ribbon 和 Eureka,从而让 Feign 的使用更加方便。

    二、Feign 组件入门:

    1、项目中需导入 feign 组件依赖坐标。

    2、在项目中配置调用 feign 组件的接口。

    3、在项目的启动类上激活 feign 组件。

    4、通过自动的接口调用远程微服务。

    三、Feign 组件入门案例搭建–准备数据库表

    — 创建数据库:
    create database shop;

    — 使用数据库:
    use shop;

    — 创建数据表:

    	CREATE TABLE `tb_product` (
    	  `id` int NOT NULL AUTO_INCREMENT,
    	  `product_name` varchar(40) DEFAULT NULL COMMENT '名称',
    	  `status` int DEFAULT NULL COMMENT '状态',
    	  `price` decimal(10,2) DEFAULT NULL COMMENT '单价',
    	  `product_desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '描述',
    	  `caption` varchar(255) DEFAULT NULL COMMENT '标题',
    	  `inventory` int DEFAULT NULL COMMENT '库存',
    	  PRIMARY KEY (`id`)
    	) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    — 插入数据:

    insert into `tb_product` (`id`, `product_name`, `status`, `price`, `product_desc`, `caption`, `inventory`) values('1','iPhone 15 Pro','1','7999.00','iPhone 15 Pro 6.7 英寸或 6.1 英寸, 超视网膜 XDR 显示屏,ProMotion 自适应刷新率技术,钛金属搭配亚光质感玻璃背板, 灵动岛功能, A17 Pro 芯片,配备 6 核图形处理器, Pro 级摄像头系统,主摄 4800 万像素 | 超广角 | 长焦, 10 倍, 支持 USB 3, 视频播放最长可达 29 小时。 ','iPhone 15 Pro 巅峰之作','99');
    
    
    • 1
    • 2

    四、Feign 组件入门案例搭建–创建父工程 spring_cloud_demo 的 maven 工程。

    1、打开 idea 创建父工程

    创建 artifactId 名为 spring_cloud_demo 的 maven 工程。

    --> idea --> File 
    --> New --> Project 
    --> Maven 
    	Project SDK: ( 1.8(java version "1.8.0_131" ) 
    --> Next 
    --> Groupld : ( djh.it )
    	Artifactld : ( spring_cloud_demo )
    	Version : 1.0-SNAPSHOT
    --> Name: ( spring_cloud_demo )
    	Location: ( C:\java-test\idea2019\spring_cloud_demo\ )	
    --> Finish
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2、在父工程 spring_cloud_demo 的 pom.xml 文件中导入依赖坐标。

    
    
    
        4.0.0
    
        djh.it
        spring_cloud_demo
        pom
        1.0-SNAPSHOT
        
            product_service
            order_service
        
    
        
            org.springframework.boot
            spring-boot-starter-parent
            2.1.6.RELEASE
        
    
        
            UTF-8
            UTF-8
            1.8
        
    
        
            
                org.springframework.boot
                spring-boot-starter-web
            
            
                org.springframework.boot
                spring-boot-starter-logging
            
            
                org.springframework.boot
                spring-boot-starter-test
                test
            
            
                org.projectlombok
                lombok
                1.18.4
                provided
            
        
    
        
            
                
                    org.springframework.cloud
                    spring-cloud-dependencies
                    Greenwich.RELEASE
                    pom
                    import
                
            
        
    
        
            
                spring-snapshots
                Spring Snapshots
                http://repo.spring.io/libs-snapshot-local
                
                    true
                
            
            
                spring-milestones
                Spring Milestones
                http://repo.spring.io/libs-milestone-local
                
                    false
                
            
            
                spring-releases
                Spring Releases
                http://repo.spring.io/libs-release-local
                
                    false
                
            
        
    
        
            
                spring-snapshots
                Spring Snapshots
                http://repo.spring.io/libs-snapshot-local
                
                    true
                
            
            
                spring-milestones
                Spring Milestones
                http://repo.spring.io/libs-milestone-local
                
                    false
                
            
        
    
        
            
                
                    org.springframework.boot
                    spring-boot-maven-plugin
                
            
        
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119

    五、Feign 组件入门案例搭建–创建 子工程 eureka_service(子模块)

    Eureka 学习链接:
    # 从浅入深 学习 SpringCloud 微服务架构(三)注册中心 Eureka(1)

    1、在父工程 spring_cloud_demo 下,创建子工程(子模块)

    创建 子工程(子模块)

    --> 右键 spring_cloud_demo 父工程
    --> Modules 
    --> Maven 
    --> Groupld : ( djh.it )
    	Artifactld : ( eureka_service )
    	Version : 1.0-SNAPSHOT
    --> Next 
    --> Module name: ( eureka_service )
    	Content root : ( \spring_cloud_demo\eureka_service )
    	Module file location: ( \spring_cloud_demo\eureka_service )
    --> Finish
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2、在子工程 eureka_service (子模块)中的 pom.xml 中导入依赖

    
    
    
        
            spring_cloud_demo
            djh.it
            1.0-SNAPSHOT
        
        4.0.0
    
        eureka_service
    
        
            
                org.springframework.cloud
                spring-cloud-starter-netflix-eureka-server
            
        
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3、在子工程 eureka_service (子模块)中,创建配置文件 application.yml 配置文件。

    
    ## spring_cloud_demo\eureka_service\src\main\resources\application.yml
    
    server:
      port: 9000  # 启动端口 命令行注入。
    
    eureka: # 配置 eureka_server
      instance:
        hostname: localhost
      client:
        register-with-eureka: false  # 是否将自己注册到注册中心
        fetch-registry: false  # 是否从 Eureka 中获取注册信息
        service-url: # 配置暴露给 EurekaClient 的请求地址
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4、在子工程 eureka_service (子模块)中,创建 启动类 EurekaServerApplication.java

    
    /**
     *   spring_cloud_demo\eureka_service\src\main\java\djh\it\eureka\EurekaServerApplication.java
     *
     *   2024-4-24  启动类 EurekaServerApplication.java
     */
    package djh.it.eureka;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.domain.EntityScan;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @SpringBootApplication
    @EnableEurekaServer  //激活 Eureka
    public class EurekaServerApplication {
        public static void main(String[] args) {
            SpringApplication.run(EurekaServerApplication.class, args);
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    5、在子工程 eureka_service (子模块)中,运行启动类,进行测试

    浏览器地址栏输入:http://localhost:9000 输出界面如下:

    在这里插入图片描述

    六、Feign 组件入门案例搭建–创建 生产者子工程 product_service(子模块)

    1、在父工程 spring_cloud_demo 下,创建子工程(子模块)

    1)创建 生产者 子工程 product_service(子模块)

    --> 右键 spring_cloud_demo 父工程
    --> Modules 
    --> Maven 
    --> Groupld : ( djh.it )
    	Artifactld : ( product_service )
    	Version : 1.0-SNAPSHOT
    --> Next 
    --> Module name: ( product_service )
    	Content root : ( spring_cloud_demo\product_service )
    	Module file location: ( spring_cloud_demo\product_service )
    --> Finish
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2、在 生产者 子工程 product_service (子模块)中的 pom.xml 中导入依赖

    
    
    
        
            spring_cloud_demo
            djh.it
            1.0-SNAPSHOT
        
        4.0.0
    
        product_service
    
        
            
                mysql
                mysql-connector-java
                 5.1.32
    
            
            
                org.springframework.boot
                spring-boot-starter-data-jpa
            
            
            
                org.springframework.cloud
                spring-cloud-starter-netflix-eureka-client
            
        
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    3、在 生产者 子工程 product_service (子模块)中,创建 商品实体类 Product.java

    
    /**
     *   spring_cloud_demo\product_service\src\main\java\djh\it\djh\it\product\domain\Product.java
     *
     *  2024-4-24 商品实体类 Product.java
     */
    package djh.it.product.domain;
    
    import lombok.Data;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;
    import java.math.BigDecimal;
    
    @Data
    @Entity
    @Table(name="tb_product")  //对应数据库中的数据表
    public class Product {
    
        @Id
        private Long id;
        private String productName;
        private Integer status;
        private BigDecimal price;
        private String productDesc;
        private String caption;
        private Integer inventory;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    4、在 生产者 子工程 product_service (子模块)中,创建 dao 持久层接口类 ProductDao.java

    
    /**
     *   spring_cloud_demo\product_service\src\main\java\djh\it\product\dao\ProductDao.java
     *
     *  2024-4-24  dao 持久层接口类 ProductDao.java
     */
    package djh.it.product.dao;
    
    import djh.it.product.domain.Product;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
    
    public interface ProductDao
            extends JpaRepository, JpaSpecificationExecutor {
    
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    5、在 生产者 子工程 product_service (子模块)中,创建 service 服务层 接口类 ProductService.java

    
    /**
     *   spring_cloud_demo\product_service\src\main\java\djh\it\product\service\ProductService.java
     *
     *  2024-4-24  service 服务层 接口类 ProductService.java
     */
    package djh.it.product.service;
    
    import djh.it.product.domain.Product;
    
    public interface ProductService {
        //根据id查询
        Product findById(Long id);
        //保存
        void save(Product product);
        //更新
        void update(Product product);
        //删除
        void delete(Long id);
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    6、在 生产者 子工程 product_service (子模块)中,创建 service 服务层 实现类 ProductServiceImpl.java

    
    /**
     *   spring_cloud_demo\product_service\src\main\java\djh\it\product\service\Impl\ProductServiceImpl.java
     *
     *  2024-4-24  service 服务层 实现类 ProductServiceImpl.java
     */
    package djh.it.product.service.Impl;
    
    import djh.it.product.domain.Product;
    import djh.it.product.dao.ProductDao;
    import djh.it.product.service.ProductService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class ProductServiceImpl implements ProductService {
    
        @Autowired
        private ProductDao productDao;
    
        @Override
        public Product findById(Long id) {
            return productDao.findById(id).get();
        }
    
        @Override
        public void save(Product product) {
            productDao.save(product);
        }
    
        @Override
        public void update(Product product) {
            productDao.save(product);
        }
    
        @Override
        public void delete(Long id) {
            productDao.deleteById(id);
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    7、在 生产者 子工程 product_service (子模块)中,创建 商品的 controller 类 ProductController.java

    
    /**
     *   spring_cloud_demo\product_service\src\main\java\djh\it\product\controller\ProductController.java
     *
     *  2024-4-24 商品的 controller 类 ProductController.java
     */
    package djh.it.product.controller;
    
    import djh.it.product.domain.Product;
    import djh.it.product.service.ProductService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    @RestController
    @RequestMapping("/product")
    public class ProductController {
    
        @Autowired
        private ProductService productService;
    
        @RequestMapping(value = "/{id}", method = RequestMethod.GET)
        public Product findById(@PathVariable Long id){
            Product product = productService.findById(id);
            return product;
        }
    
        @RequestMapping(value = "", method = RequestMethod.POST)
        public String save (@RequestBody Product product){
            productService.save(product);
            return "保存成功";
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    8、在 生产者 子工程 product_service (子模块)中,创建配置文件 application.yml

    
    ##  spring_cloud_demo\product_service\src\main\resources\application.yml
    
    server:
      port: 9001 #端口
    
    spring:
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    #    url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8
        username: 'root'
        password: '012311'
      application:
        name: service-product #服务名称
      jpa:
        database: MySQL
        show-sql: true
        open-in-view: true
    
    eureka:  # 配置 Eureka
      client:
        service-url:
          defaultZone: http://localhost:9000/eureka/
      instance:
        prefer-ip-address: true  # 使用 ip 地址注册
        instance-id: ${spring.cloud.client.ip-address}:${server.port}
    
    #spring:
    #  application:
    #    name: service-product #服务名称
    #  datasource:
    #    driver-class-name: com.mysql.jdbc.Driver
    #    url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8
    #    username: root
    #    password: 012311
    #  jpa:
    #    database: MySQL
    #    show-sql: true
    #    open-in-view: true
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    9、在 生产者 子工程 product_service (子模块)中,创建 启动类 ProductApplication.java

    
    /**
     *   spring_cloud_demo\product_service\src\main\java\djh\it\product\ProductApplication.java
     *
     *   2024-4-24  启动类 ProductApplication.java
     */
    package djh.it.product;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.domain.EntityScan;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @SpringBootApplication
    @EntityScan("djh.it.product.domain")
    @EnableEurekaClient  //激活 EurekaClient, 同 @EnableDiscoveryClient 注解相同。
    public class ProductApplication {
        public static void main(String[] args) {
            SpringApplication.run(ProductApplication.class, args);
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    10、在 生产者 子工程 product_service (子模块)中,运行启动类,进行测试

    浏览器地址栏输入:http://127.0.0.1:9001/product/1

    输出 mysql 数据库的第一条记录:

    在这里插入图片描述

    七、Feign 组件入门案例搭建–创建 消费者子工程 order_service(子模块)

    1、在父工程 spring_cloud_demo 下,创建子工程(子模块)

    创建 消费者 子工程(子模块)order_service

    --> 右键 spring_cloud_demo 父工程
    --> Modules 
    --> Maven 
    --> Groupld : ( djh.it )
    	Artifactld : ( order_service )
    	Version : 1.0-SNAPSHOT
    --> Next 
    --> Module name: ( order_service )
    	Content root : ( \spring_cloud_demo\order_service )
    	Module file location: ( \spring_cloud_demo\order_service )
    --> Finish
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2、在消费都子工程(子模块) order_service 的 pom.xml 中导入依赖

    
    
    
        
            spring_cloud_demo
            djh.it
            1.0-SNAPSHOT
        
        4.0.0
    
        order_service
    
        
            
                mysql
                mysql-connector-java
                5.1.32
                
            
            
                org.springframework.boot
                spring-boot-starter-data-jpa
            
            
            
                org.springframework.cloud
                spring-cloud-starter-netflix-eureka-client
            
             
            
                org.springframework.cloud
                spring-cloud-starter-openfeign
            
        
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    3、在消费都子工程(子模块) order_service 中,创建配置文件 application.yml

    
    ##  spring_cloud_demo\order_service\src\main\resources\application.yml
    
    server:
      port: 9002 #端口
    #  port: ${port:9002}  # 启动端口设置为动态传参,如果未传参数,默认端口为 9002
    
    spring:
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
    #    url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
        url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8
        username: 'root'
        password: '012311'
      application:
        name: service-order #服务名称
      jpa:
        database: MySQL
        show-sql: true
        open-in-view: true
    
    eureka:  # 配置 Eureka
      client:
        service-url:
          defaultZone: http://localhost:9000/eureka/
      instance:
        prefer-ip-address: true  # 使用 ip 地址注册
        instance-id: ${spring.cloud.client.ip-address}:${server.port}
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    4、在消费都子工程(子模块) order_service 中,创建 商品实体类 Product.java

    
    /**
     *   spring_cloud_demo\order_service\src\main\java\djh\it\order\domain\Product.java
     *
     *  2024-4-24 商品实体类 Product.java
     */
    package djh.it.order.domain;
    
    import lombok.Data;
    import java.math.BigDecimal;
    
    @Data
    public class Product {
    
        private Long id;
        private String productName;
        private Integer status;
        private BigDecimal price;
        private String productDesc;
        private String caption;
        private Integer inventory;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    5、在消费都子工程(子模块) order_service 中,创建 controller 类 OrderController.java

    
    /**
     *   spring_cloud_demo\order_service\src\main\java\djh\it\order\controller\OrderController.java
     *
     *  2024-4-24 订单的 controller 类 OrderController.java
     */
    package djh.it.order.controller;
    
    import djh.it.order.domain.Product;
    import djh.it.order.feign.ProductFeignClient;
    import org.springframework.beans.factory.annotation.Autowired;
    //import org.springframework.cloud.client.discovery.DiscoveryClient;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    //import org.springframework.web.client.RestTemplate;
    
    @RestController
    @RequestMapping("/order")
    public class OrderController {
    
    //    // 注入 restTemplate 对象
    //    @Autowired
    //    private RestTemplate restTemplate;
    
        @Autowired   //注入 feign 组件的接口类
        private ProductFeignClient productFeignClient;
    
        /**
         *  注入 DiscoveryClient : springcloud 提供的获取元数据的工具类。
         *      调用方法获取服务的元数据信息。
         */
    //    @Autowired
    //    private DiscoveryClient discoveryClient;
    
        /**
         *  使用 基于 ribbon 的形式调用远程微服务:
         *  1、使用 @LoadBalanced 注解 声明 RestTemplate
         *  2、使用服务名称 service-product 替换 IP 地址 。
         *
         * @param id
         * @return
         */
        @RequestMapping(value = "/buy/{id}", method = RequestMethod.GET)
        public Product findById(@PathVariable Long id){
            Product product = null;
    //        //product = restTemplate.getForObject("http://127.0.0.1:9001/product/1", Product.class);
    //        product = restTemplate.getForObject("http://service-product/product/1", Product.class);
    
             //通过 Feign 自动的接口调用远程微服务
            product = productFeignClient.findById(id);
    
            return product;
        }
    
    
        /**
         *  参数:商品的 id
         *      通过订单系统,调用商品服务根据id查询商品信息。
         *          1)需要配置商品对象。
         *          2)需要调用商品服务。
         *   可以使用 java 中的 urlconnection, HttpClient, OkHttp 进行远程调用。
         *   也可以使用 restTemplate 进行远程调用。
         *
         * @param id
         * @return
         */
    //    @RequestMapping(value = "/buy/{id}", method = RequestMethod.GET)
    //    public Product findById(@PathVariable Long id){
    //
    //        //调用 discoveryClient 方法,已调用服务名称获取所有的元数据。
    //        List instances = discoveryClient.getInstances("service-product");
    //        for (ServiceInstance instance : instances) {
    //            System.out.println(instance);
    //        }
    //
    //        //获取唯一的一个元数据
    //        ServiceInstance instance = instances.get(0);
    //
    //        Product product = null;
    //
    //        //根据元数据中的主机地址和端口号拼接请求微服务的 URL
    //        product = restTemplate.getForObject("http://" + instance.getHost() + ":" + instance.getPort() + "/product/1", Product.class);
    //
    //
    //        /**
    //         *  调用商品服务(将微服务的请求路径硬编码到 java 代码中)
    //         *  存在问题:对微服务调用的负载均衡,加入API网关,配置的统一管理,链路追踪。
    //         */
    //        //product = restTemplate.getForObject("http://127.0.0.1:9001/product/1", Product.class);
    //        return product;
    //    }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96

    6、在消费都子工程(子模块) order_service 中,调用 feign 组件的接口类 ProductFeignClient.java

    
    /**
     *   spring_cloud_demo\order_service\src\main\java\djh\it\order\feign\ProductFeignClient.java
     *
     *   2024-4-24  调用 feign 组件的接口类 ProductFeignClient.java
     *   声明需要调用的微服务名称 @FeignClient, name: 服务提供者的名称
     */
    
    package djh.it.order.feign;
    
    import djh.it.order.domain.Product;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    @FeignClient(name="service-product")
    public interface ProductFeignClient {
        //配置需要调用的微服务接口
        @RequestMapping(value = "/product/{id}", method = RequestMethod.GET)
        public Product findById(@PathVariable("id") Long id);
    }
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    7、在消费都子工程(子模块) order_service 中,创建 启动类 OrderApplication.java

    
    /**
     *   spring_cloud_demo\order_service\src\main\java\djh\it\order\OrderApplication.java
     *
     *   2024-4-24  启动类 OrderApplication.java
     */
    package djh.it.order;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.domain.EntityScan;
    //import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    //import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    //import org.springframework.context.annotation.Bean;
    //import org.springframework.web.client.RestTemplate;
    
    @SpringBootApplication
    @EntityScan("djh.it.order.domain")
    //@EnableEurekaClient  //激活 EurekaClient, 同 @EnableDiscoveryClient 注解相同。
    @EnableFeignClients   //激活 Feign 组件。
    public class OrderApplication {
    
        /**
         *  使用 spring 提供的 RestTemplate 发送 http 请求到商品服务。
         *      1)创建 RestTemplate 对象交给容器管理。
         *      2)在使用的时候,调用其方法完成操作(getXX, postXX)。     *
         */
    //    @LoadBalanced
    //    @Bean
    //    public RestTemplate restTemplate(){
    //        return new RestTemplate();
    //    }
    
        public static void main(String[] args) {
            SpringApplication.run(OrderApplication.class, args);
        }
    }
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    8、运行启动类,进行测试

    浏览器地址栏输入:http://127.0.0.1:9002/order/buy/1

    输出 mysql 数据库的第一条记录:

    在这里插入图片描述

    上一节链接
    # 从浅入深 学习 SpringCloud 微服务架构(五)Consul(2)

  • 相关阅读:
    如何使用 Nginx 创建临时和永久重定向
    无法将“node.exe”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
    (附源码)springboot 病例管理系统 毕业设计 641645
    【JVM 系列】JVM 调优
    [go学习笔记.第十三章.单元测试] 1.单元测试
    活字格性能优化技巧(1)——如何利用数据库主键提升访问性能
    如何排查SQL慢查询?
    AntDB入选《2022爱分析·信创厂商全景报告》
    【重拾C语言】四、循环程序设计(后判断条件循环、先判断条件循环、多重循环;典例:计算平均成绩、打印素数、百钱百鸡问题)
    Docker 安装部署 Gitlab 存储路径迁移
  • 原文地址:https://blog.csdn.net/qfyh_djh/article/details/138172847