Feign


Feign [fe ɪ n]

What is Feign?

Feign, which stands for “fake, disguise, and transform,” is a lightweight framework for calling HTTP requests using Java interface annotations, rather than using Java as a wrapper for HTTP requests. Feign templates the request by processing the annotations, and when it is actually invoked, it passes in parameters that are then applied to the request, turning it into a real request, which is relatively straightforward. Feign is widely used in Spring Cloud solutions and is an essential component of learning about Spring Cloud-based microservices architecture. SpringCloud integrates with the Ribbon Eureka to provide load-balancing clients when using Feign

You just need an interface and add annotations

Feign is mostly a community, and people are used to programming to interfaces. This is the norm for many developers. There are two ways to invoke a microservice

  • Microservice name (Ribbon)
  • Interfaces and Annotations (feign)

What can Feign do

  • Feign aims to make it easier to write Java Http clients
  • When the Ribbon + RestTemplate was used earlier, there was a modular use of RestTemplate to encapsulate Http requests. However, in the actual development, because the service dependency may be invoked in more than one place, often an interface will be invoked in multiple places, so each service will encapsulate some client classes to wrap the invocation of these dependent services. So Feign takes this one step further and helps us define and implement the definition of the dependent service interface. ** With Feign’s implementation, we just create an interface and configure it using annotations (similar to @mapper annotations on Dao interfaces). Now it’s a microservice interface with a Feign annotation on it. This simplifies the process of automatically encapsulating development for service invocation clients using SpringCloud Ribbon

Using feign instead of RestTemplate

The specific implementation

Adding interfaces (and annotations) to entity class items

The project structure

pom


      

<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>springcloud</artifactId>

        <groupId>cn.com.codingce</groupId>

        <version>1.0 the SNAPSHOT</version>

    </parent>

    <modelVersion>4.0.0</modelVersion>



    <artifactId>springcloud-api</artifactId>



    <dependencies>

        <! -- Dependencies required by the current Module itself, if the parent dependency has a version configured -->

        <dependency>

            <groupId>org.projectlombok</groupId>

            <artifactId>lombok</artifactId>

        </dependency>



        <! --junit-->

<! -- <dependency>-->

<! -- <groupId>junit</groupId>-->

<! -- <artifactId>junit</artifactId>-->

<! -- </dependency>-->



        <! --feign-->

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-feign</artifactId>

            <version>1.4.6. RELEASE</version>

        </dependency>



        <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

        </dependency>



        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>druid</artifactId>

        </dependency>



    </dependencies>

</project>

Copy the code

DeptClientService

package cn.com.codingce.service;



import cn.com.codingce.pojo.Dept;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.stereotype.Component;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.PostMapping;



import java.util.List;



/ * *

 * @author xzMa

 *

* Feign (Programming on interfaces) exercise create service package in entity class project and create DeptClientService interface

 *

 *

* Two ways to call microservices: 1 microservice name ribbon 2 interface and annotation FEign

 *

 *

* Only interfaces and annotations are needed

 *

* note

* /


@Component

@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")

public interface DeptClientService {



    / / interface



    @GetMapping("/dept/get/{id}")

    public Dept queryById(@PathVariable("id") Long id);



    @GetMapping("/dept/list")

    public List<Dept> queryAll(a);



    @PostMapping("/dept/add")

    public boolean addDept(Dept dept);



}

Copy the code

Create a new client project (Springcloud-Cusumer-dept-feign)

The project structure

pom


      

<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>springcloud</artifactId>

        <groupId>cn.com.codingce</groupId>

        <version>1.0 the SNAPSHOT</version>

    </parent>

    <modelVersion>4.0.0</modelVersion>

    <description>It's also used as a client</description>

    <artifactId>springcloud-cusumer-dept-feign</artifactId>



    <dependencies>

        <! --feign-->

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-feign</artifactId>

            <version>1.4.6. RELEASE</version>

        </dependency>



        <! We need to get the entity class, so we need to configure api-module -->

        <dependency>

            <groupId>cn.com.codingce</groupId>

            <artifactId>springcloud-api</artifactId>

            <version>1.0 the SNAPSHOT</version>

        </dependency>



        <! -- Hot Deployment Tool -->

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-devtools</artifactId>

        </dependency>



        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>



        <! --Ribbon-->

        <! -- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon -->

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-ribbon</artifactId>

            <version>1.4.6. RELEASE</version>

        </dependency>



        <! --Eureka client -->

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-eureka</artifactId>

            <version>1.4.6. RELEASE</version>

        </dependency>

    </dependencies>

</project>

Copy the code

DeptConsumerController

package cn.com.codingce.springcloud.controller;



import cn.com.codingce.pojo.Dept;

import cn.com.codingce.service.DeptClientService;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;



import javax.annotation.Resource;

import java.util.List;



@RestController

public class DeptConsumerController {



    @Resource

    private DeptClientService deptClientService = null;



    @RequestMapping("/consumer/dept/add")

    public boolean add(Dept dept) {

        return this.deptClientService.addDept(dept);

    }



    @RequestMapping("/consumer/dept/get/{id}")

    public Dept get(@PathVariable("id") Long id) {

        return this.deptClientService.queryById(id);

    }



    @RequestMapping("/consumer/dept/list")

    public List<Dept> list(a) {

        return this.deptClientService.queryAll();

    }



}

Copy the code

Ribbon ConfigBean (configuration)

package cn.com.codingce.springcloud.config;



import com.netflix.loadbalancer.IRule;

import com.netflix.loadbalancer.RandomRule;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.client.RestTemplate;



@Configuration

public class ConfigBean {   //configuration -- spring applicationContext.xml



    // Configure load balancing for RestTemplate @loadBalanced

    //IRule

    / / AvailabilityFilteringRule: will filter out first, tripping, access to the failed server

    / / RoundRobinRule polling

    / / RandomRule random

    //RetryRule: the service is obtained based on polling. ~ If the service fails to be obtained, the service is retried within the specified time

    @Bean

    @LoadBalanced

    public RestTemplate getRestTemplate(a) {

        return new RestTemplate();

    }





    @Bean

    public IRule myRule(a) {

        return new RandomRule();

    }



}

Copy the code

Start the class FeginDeptConsumer_80

package cn.com.codingce.springcloud;



import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

import org.springframework.cloud.openfeign.EnableFeignClients;

import org.springframework.context.annotation.ComponentScan;



/ * *

 * @author xzMa

* Our custom Ribbon classes can be loaded when the microservice is started

* /


@SpringBootApplication

@EnableEurekaClient / / had the client

@EnableFeignClients(basePackages = {"cn.com.codingce"})

@ComponentScan("cn.com.codingce")

public class FeginDeptConsumer_80 {

    public static void main(String[] args) {

        SpringApplication.run(FeginDeptConsumer_80.class, args);

    }

}

Copy the code

The operation screenshot

Open source address of the project: the project address: https://github.com/xzMhehe/codingce-java https://github.com/OpenFeign/feign