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

发布于:2024-04-25 ⋅ 阅读:(22) ⋅ 点赞:(0)

从浅入深 学习 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

— 插入数据:

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');

四、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

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


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>djh.it</groupId>
    <artifactId>spring_cloud_demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>product_service</module>
        <module>order_service</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>http://repo.spring.io/libs-snapshot-local</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>http://repo.spring.io/libs-milestone-local</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>http://repo.spring.io/libs-release-local</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>http://repo.spring.io/libs-snapshot-local</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>http://repo.spring.io/libs-milestone-local</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
<!-- spring_cloud_demo\pom.xml -->

五、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

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


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>djh.it</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka_service</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

</project>
<!-- spring_cloud_demo\eureka_service\pom.xml -->

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/


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);
    }
}


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

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


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>djh.it</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>product_service</artifactId>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
             <version>5.1.32</version>
<!--            <version>8.0.23</version>-->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- 引入 EurekaClient 依赖坐标 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

</project>

<!-- spring_cloud_demo\product_service\pom.xml -->

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;
}


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<Product, Long>, JpaSpecificationExecutor<Product> {

}


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);
}


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);
    }
}


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 "保存成功";
    }
}


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


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);
    }
}


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

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


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>djh.it</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>order_service</artifactId>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.32</version>
            <!--            <version>8.0.23</version>-->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- 引入 EurekaClient 依赖坐标 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
         <!-- springcloud 整合的openFeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

</project>
<!-- spring_cloud_demo\order_service\pom.xml -->

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}


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;
}

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<ServiceInstance> 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;
//    }
}


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);
}



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);
    }
}



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

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

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

在这里插入图片描述

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