当前位置: 首页 > news >正文

feign漫谈

feign的简单使用。

文章目录

  • 什么是feign
  • 准备工作
  • 三.如何使用
    • 3.1 定义pom文件
    • 3.2 定义配置文件及启动类注解
    • 3.3 定义feign接口

什么是feign

远程调用框架

准备工作

需要nacos环境:

涉及到feign调用,就没法抛开注册中心,接下来我们使用主流的nacos作为注册中心进行搭建本地环境。具体参见之前的nacos系列:https://blog.csdn.net/imVainiycos/article/details/122917022

三.如何使用

3.1 定义pom文件

  1. 新建一个maven项目作为父工程

image-20230116160204225

父工程的pom文件如下:

<?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>com.vainycos</groupId>
    <artifactId>demo-spring-cloud</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <!-- 预留三个模块 -->
        <module>core</module>
        <module>customer</module>
        <module>supermarket</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <springboot.version>2.2.5.RELEASE</springboot.version>
        <spring.cloud.version>Hoxton.SR3</spring.cloud.version>
        <spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!--支持Spring Boot 2.1.X-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${springboot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- alibaba-cloud -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring.cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!--服务调用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-okhttp</artifactId>
        </dependency>
        <!--注册中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

</project>
  1. 新建三个子模块,模拟一个超市购物行为和结账会员身份识别场景,分别是:
  • core - 核心模块,feign接口层或者其他核心类
  • customer - 会员模块,依赖[core]模块,通过core模块的feign统一调用[supermarket]服务
  • supermarket - 超市模块,依赖[core]模块,通过core模块的feign统一调用[customer]服务

​ core模块的pom文件:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.vainycos</groupId>
        <artifactId>demo-spring-cloud</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.vainycos</groupId>
    <artifactId>core</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>core</name>
    <description>core</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <!-- spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

​ customer模块的pom文件:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.vainycos</groupId>
        <artifactId>demo-spring-cloud</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.vainycos</groupId>
    <artifactId>customer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>customer</name>
    <description>customer</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.vainycos</groupId>
            <artifactId>core</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

​ supermarket模块的pom文件:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.vainycos</groupId>
        <artifactId>demo-spring-cloud</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>supermarket</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>supermarket</name>
    <description>supermarket</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.vainycos</groupId>
            <artifactId>core</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.2 定义配置文件及启动类注解

假设你本地的nacos已经启动完成了,启动端口为默认的8848。

两个模块的配置均大同小异,这里以customer模块为例。

这里需要注意由于使用微服务的配置需要优先加载,所以我们不在原来的application.yaml或者application.yml上进行配置,而是新建一个bootstrap.yml文件进行配置,配置内容如下:

server:
  # 定义另一个模块的启动端口为8082
  port: 8081

spring:
  application:
  	# 定义另一个模块的值为market
    name: customer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

在启动类CustomerApplication上加注解@EnableDiscoveryClient以及@EnableFeignClients(basePackageClasses = {CustomerApplication.class, CoreApplication.class}),这里需要依赖core模块,所以把core的启动类也注入。

@EnableDiscoveryClient
@EnableFeignClients(basePackageClasses = {CustomerApplication.class, CoreApplication.class})
@SpringBootApplication
public class CustomerApplication {

    public static void main(String[] args) {
        SpringApplication.run(CustomerApplication.class, args);
    }

}

3.3 定义feign接口

首先我们在customer模块定义一个接口,根据id查询客户信息:

@RequestMapping("/customer")
@RestController
public class CustomerController {

    @Autowired
    private MarketService marketService;

    @GetMapping("/getUser/{id}")
    public String getById(@PathVariable("id") Integer id){
        return "获取id=" + id + "的用户";
    }
}

调用本服务进行测试,访问/customer/getUser/1,结果如下表示通过:

image-20230116155257137

我们到core模块下定义一个feign接口CustomerService,在类名上加注解@FeignClient(name = “customer”),该注解name的值需要注意与调用服务方配置文件重的application.name保持一致,比如这里是customer:

image-20230116171123037

完整的feign接口定义如下,这里需要注意每个入参都需要定义入参格式,比如这里是路径参数即加上@PathVariable,其他的还有@RequestParameter,@RequestBody等等,并且@GetMapping的请求地址需要与对应模块的请求地址保持一致:

package com.vainycos.core.feign.customer;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "customer")
public interface CustomerService {

    @GetMapping("/customer/getUser/{id}")
    String getCustomerById(@PathVariable("id") Integer id);
}

这个时候我们模拟一个场景,即在supermarket模块结账的时候需要调用customer模块获取会员信息。

在supermarket模块中定义controller,把上面的feign接口注入进来即可调用:

package com.example.supermarket.controller;

import com.vainycos.core.feign.customer.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author: Vainycos
 * @description
 * @date: 2023/1/16 13:30
 */
@RequestMapping("/market")
@RestController
public class MarketController {

    @Autowired
    private CustomerService customerService;

    @GetMapping("/buy")
    public String order(String things, Integer id){
        String customerById = customerService.getCustomerById(id);
        return customerById + "购买了" +things;
    }
}

访问/market/buy?things=苹果电脑&id=1,结果如下:

image-20230116171607683

到这里,完整的feign调用链路就已经搭建完成了。

同理,我们也可以在supermarket定义获取商品列表的服务,然后提供给customer调用:

package com.example.supermarket.controller;

import com.vainycos.core.feign.customer.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author: Vainycos
 * @description
 * @date: 2023/1/16 13:30
 */
@RequestMapping("/market")
@RestController
public class MarketController {

    @Autowired
    private CustomerService customerService;

    /**
     * 获取商品列表
     * @return
     */
    @GetMapping("/listMarket")
    public String listMarket(){
        return "啤酒,瓜子,花生米";
    }
    
    @GetMapping("/buy")
    public String order(String things, Integer id){
        // 调用feign接口
        String customerById = customerService.getCustomerById(id);
        return customerById + "购买了" +things;
    }
    
}

然后在core模块下定义feign接口

package com.vainycos.core.feign.supermarket;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @author: Vainycos
 * @description
 * @date: 2023/1/16 16:18
 */
@FeignClient(name = "market")
public interface MarketService {

    @GetMapping("/market/listMarket")
    String listMarket();
}

最后在customer模块中注入feign接口MarketService进行使用:

package com.vainycos.customer.controller;

import com.vainycos.core.feign.supermarket.MarketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author: Vainycos
 * @description
 * @date: 2023/1/16 13:27
 */
@RequestMapping("/customer")
@RestController
public class CustomerController {

    @Autowired
    private MarketService marketService;

    @GetMapping("/listMarket/{id}")
    public String listMarket(@PathVariable("id") Integer id){
        // 调用feign接口
        String goods = marketService.listMarket();
        return "用户id=" + id + "查询商品列表:" + goods;
    }
    
    @GetMapping("/getUser/{id}")
    public String getById(@PathVariable("id") Integer id){
        return "获取id=" + id + "的用户";
    }
    
}

访问/customer/listMarket/1,结果如下:

image-20230116172124042

参考资料:

  • Feign的使用
  • 什么是Feign?
  • 【微服务】分布式组件 Nacos 结合 Feign 的使用

相关文章:

  • 五百亿网站搬家公司/互联网舆情监控系统
  • iis上做的网站外网怎么访问不了/廊坊网站seo
  • 网站需求分析怎么做/河南企业网站建设
  • 网站建设业务的途径的体会/腾讯广告投放推广平台
  • 溧阳网站建设公司/百度一下京东
  • 网上政务服务平台入口/seo手机端排名软件
  • 1.浮动float
  • hud 1846巴什博弈(简单的解法 或 Sprague-Grundy解法)
  • Pytorch深度学习【十四】
  • CodeForces 438D The Child and Sequence(线段树区间取模)
  • Linux——系统管理篇
  • 【Java】面向对象笔记(中)(二)
  • 注册中心和负载均衡(黑马SpringCloud笔记)
  • DSPE-PEG-Silane,磷脂-聚乙二醇-硅烷,简介。可用于修饰玻璃、二氧化硅颗粒和许多其他材料表面
  • Acwing---1229.日期问题
  • 01.数据的存储.练习题
  • 1.6 阿达马积
  • verilog学习笔记- 14)静态数码管显示实验