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