I. Overview
In a microservice architecture, calls between services are very frequent. In order to simplify calls between services, Spring Boot provides a component called Feign. Feign can help us define and implement RESTful interfaces between services.
The @FeignClient annotation is a component in Spring Cloud, implemented based on Netflix Feign. The @FeignClient annotation can help us define and implement RESTful interfaces between services, making calls between services more convenient and reliable.
- Analysis of @FeignClient annotation principle
(1) Working principle: - First enable FeignCleint through the @EnableFeignCleints annotation on the springboot startup class.
- Implement the interface according to Feign’s rules and add the @FeignCleint annotation. After the program starts, it will scan all classes with @FeignCleint and inject these classes into the spring IOC container.
- Get FeignClient from FeignClientFactoryBean.class when injecting.
- When the interface defined in @FeignClient is called, the RequestTemplate is generated through the dynamic proxy of JDK. RequestTemplate contains all information of the request, such as request parameters, request URL, etc.
- The request is handed over to the client for processing. The default client is JDK’s HTTPUrlConnection, or it can be OKhttp, Apache’s HTTPClient, etc.
- Finally, the client is encapsulated into LoadBaLanceClient, and the call is initiated in conjunction with ribbon load balancing.
(2) Analysis:
The core of Feign remote calling is that through a series of encapsulation and processing, the remote calling API interface defined in the form of JAVA annotations is finally converted into an HTTP request form, and then the response result of the HTTP request is decoded into a JAVA Bean and returned to the caller.
(3) The core of the @FeignClient annotation
The core components annotated with @FeignClient include Feign.Builder, FeignClientFactoryBean and FeignClientsRegistrar.
1.Feign.Builder: used to generate Feign proxy objects. Feign.Builder can generate a Java interface based on the specified HTTP API interface and automatically inject it into the Ribbon for load balancing.
2.FeignClientFactoryBean: used to create Feign’s proxy object. FeignClientFactoryBean can generate a proxy object based on the specified HTTP API interface and Feign.Builder and inject it into the Spring container.
3.FeignClientsRegistrar: used to register the @FeignClient annotation. FeignClientsRegistrar can scan all @FeignClient annotations in the project and register them in the Spring container.
(4) Properties in the @FeignClient annotation
value: service name (service name of the interface provider)
path: defines the unified path prefix of the current FeignClient
name: Specify the name of FeignClient. If the project uses Ribbon or spring-cloud-loadbalancer, the name attribute will be used as the name of the microservice for service discovery.
contextId: Identifier for resolving bean name conflicts
url: URL is generally used for debugging. You can manually specify the address called by @FeignClient.
decode404: When an http 404 error occurs, if this field is true, the decoder will be called to decode, otherwise a FeignException will be thrown.
configuration: Feign configuration class, you can customize Feign’s Encoder, Decoder, LogLevel, and Contract
fallback: Define a fault-tolerant processing class. When calling the remote interface fails or times out, the fault-tolerant logic of the corresponding interface will be called. The class specified by fallback must implement the interface marked by @FeignClient.
fallbackFactory: Factory class, used to generate fallback class examples. Through this attribute, we can implement common fault-tolerant logic for each interface and reduce repeated code.
- Use of @FeignClient annotation
- Add maven dependencies
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
- Write a new controller class.
@RestController
public class FileController {
@PostMapping(value = "/demo/upload")
Result<FileInfo> uploadFile(@RequestPart(value = "file") MultipartFile file) {
return new Result();
}
}
- Define Feign interface
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
@FeignClient(contextId="FileFeignClient ",name = "file-upload", url = "http://127.0.0.1:8001")
public interface FileFeignClient {
@PostMapping(value = "/demo/upload",consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
Result<FileInfo> uploadFile(@RequestPart(value = "file") MultipartFile file);
}
- Create a new Spring Boot startup class
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class SpringBootFeignApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootFeignApplication .class, args);
}
}
Start the project and try to call it.
- If you want to use Apache’s httpclient connection pool, you can configure the following:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>9.7.0</version>
</dependency>
Add property configuration
feign:
okhttp:
enabled: false
httpclient:
enabled: true
maxConnections: 20480
maxConnectionsPerRoute: 512
timeToLive: 60
connectionTimeout: 10000