Spring cloud learning - Feign details (with code compression package)

Keywords: Java Spring Cloud

preface

Previous: detailed explanation of Ribbon
What is Feign? It can help us realize interface oriented programming, directly call other services in this service, and simplify development. From Eureka complex configuration, to Ribbon, and then to Feign, new components will make development easier. The following is a direct demonstration. If you haven't learned the first two, look at my previous two articles. The cases are progressive layer by layer

1, Feign preliminary actual combat

Similarly, it will be easier to use Feign to complete the Ribbon effect in the previous section
Step 1:
In Eureka_ client_ Import Feign dependency in customer's pom.xml

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

Step 2:
Add the @ EnableFeignClients annotation to the startup class

Step 3
Create an interface. Here, create PayClient

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient("payClient")   //Write the service name to find other target services
public interface PayClient {
	
	//The content of the target service is the same as that written on it, and then access here to call the pay method of the payClient service. The meaning of advantage rewriting
    @RequestMapping(value = "/pay",method = RequestMethod.GET) 
    String pay();   //pay method of payment service
}

Step 4:
The Feign method is used in the CustomerController, which is cleaner than Eureka and Ribbon. Only a little can access the pay service with one interface

@RestController
public class CustomerController {

   @Autowired
   private PayClient payClient; //Add to inject the defined interface mode

    @GetMapping("/customer")
    public String client(){
    
        String res = payClient.pay(); //Just call it
        return res;
    }
}

Finally, we restart the ClientCustomerApplication. At this time, all five services should be started
input http://localhost:8080/customer

2, Feign with transfer parameters

1. Use @ PathVariable for a single parameter
2. Use @ RequestParam for multiple parameters. Do not omit value = ""
3. The transfer object adopts @ RequestBody uniformly

Step 1: import dependencies and start Feign
eureka_client_customer's pom.xml adds a dependency, and as a consumer (service caller, calling other services), Feign needs to be enabled in the startup class

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

eureka_client_pay's pom.xml also adds dependencies

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

eureka_client_pay adds an Order entity

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {

    private Integer id;

    private String name;

    private Integer price;

}

PayController adds some new services for users to call, / pay/{id}, / getOrder, / save, which are related to the payment order. How can the Customer module use the services of the Pay module? Previously, Eureka and Ribbon can be used, but it is more troublesome than Feign

import com.yx.entity.Order;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

@RestController
public class PayController {

    @Value("${server.port}")
    private String port;

    @GetMapping("/pay")
    public String pay(){
        String msg = "Xiaoming bought a power bank and paid successfully" + port;
        return msg;
    }

    @GetMapping("/pay/{id}")
    public Order findById(@PathVariable Integer id){
        return new Order(id, "portable battery", 66);
    }

    @GetMapping("/getOrder")
    public Order getOrder(@RequestParam Integer id, @RequestParam String name){
        return new Order(id, name, 66);
    }

    @PostMapping("/save")   //RequestBody cannot use get, but use post
    public Order save(@RequestBody Order order){
        return order;
    }
}

Step 2: define the interface
Feign only needs to define an interface at the consumer (caller), that is, a PayClient interface in the customer

Note that the interface is decorated with @ FeignClient("payClient"). payClient is the name of the service to be called. Make a mapping. We want to use the payment service. Therefore, write the name of the payment service and configure the service name in application.yml

import com.yx.entity.Order;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

@FeignClient("payClient")   //Write the service name to make a mapping
public interface PayClient {
    //GetMapping is not allowed in the Client interface. It can only be RequestMapping

    @RequestMapping(value = "/pay",method = RequestMethod.GET)
    String pay();   //pay method of payment service

    @RequestMapping(value = "/pay/{id}",method = RequestMethod.GET)
    Order findById(@PathVariable(value = "id") Integer id); //To write value

    @RequestMapping(value = "/getOrder",method = RequestMethod.GET)
    Order getOrder(@RequestParam(value = "id") Integer id, @RequestParam(value = "name") String name);//Parameters must be specified with RequestParam

    @RequestMapping(value = "/save",method = RequestMethod.POST)
    Order save(@RequestBody Order order);
}

You will find that the abstract methods inside are written according to the PayController method. Yes, you can understand that the methods in PayController are concrete implementations

After defining the interface, you can use the interface. It is used in the CustomerController. The port of the customer module is 8080

import com.yx.client.PayClient;
import com.yx.entity.Order;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CustomerController {

    @Autowired
    private PayClient payClient;

    @GetMapping("/customer")
    public String client(){

        String res = payClient.pay();
        return res;
    }

    @GetMapping("/customer/{id}")
    public Order findById(@PathVariable Integer id){
        return payClient.findById(id);
    }

    @GetMapping("/CustomerOrder")
    public Order getOrder(@RequestParam Integer id, @RequestParam String name){
        return payClient.getOrder(id,name);
    }

    @GetMapping("/save")
    public Order save(Order order){
        return payClient.save(order);
    }
}

We can enter the following address in the browser to get the result

Look at the execution process behind it. Taking localhost:8080/customer/2 as an example, Eureka can be obtained indirectly in the form of interface oriented_ client_ Services provided by PayController in pay module

Code compression package:
Link: https://pan.baidu.com/s/1UI44KDXshnP4GU91nzyi9g
Extraction code: b5vy

Posted by mrwutang on Tue, 05 Oct 2021 10:57:53 -0700