Declarative calling - SpringCloud OpenFeign

Introduction to Feign

Spring Cloud Feign is a lightweight framework for HTTP request calling. HTTP requests can be called in the form of Java interface annotations instead of directly calling by encapsulating HTTP request messages.

Feign templates the request by processing annotations. When it is actually called, the parameters are passed in, and then applied to the request according to the parameters, and then converted into a real request.


The first Feign program

This section introduces how to implement calls between services through Nacos+Feign, create new server-01 and server-02 projects, and register Nacos respectively.

server-01 introduces dependencies

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

Create a new Server02FeignClient interface to call the external interface provided by server-02

// name:要调用的服务名
FeignClient(name = "server-02")
public interface Server02FeignClient {
    
    

    @GetMapping("/test/getConfig")
    void getConfig();
}

Add annotations to the startup class@EnableFeignClients

@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class Server01Application {
    
    

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

Use Server02FeignClient to call the interface of server-02

@Slf4j
@RestController
public class TestCon {
    
    
    
    @Autowired
    private Server02FeignClient server02FeignClient;

    @GetMapping("/test/getConfigByFeign")
    public void getConfigByFeign() {
    
    
        server02FeignClient.getConfig();
    }
}

Create an interface on server-02

@Slf4j
@RestController
public class TestCon {
    
    

    @Value("${test.value}")
    private String testValue;

    @Value("${spring.application.name}")
    private String applicationName;

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

    @GetMapping("/test/getConfig")
    public void getConfig() {
    
    
        log.info("testValue: {} by {}-{}", testValue, applicationName, port);
    }
}

Calling the interface of server-01 /test/getConfigByFeignwill call /test/getConfigthe interface of server-02 through Feign.

@FeignClientAnnotations can be applied to classes, interfaces, and enumerations, and mainly include the following attributes:

  • name/value: name is an alias of vaue, and value is also an alias of name. The functions of the two are the same. Use the name of the designated FeignClient. If used with the registration center, it will be used as the name of the microservice for service discovery.

  • url: Mainly used for debugging, you can manually specify @FeignClientthe calling address

  • path: path is used to define the unified prefix of the current FeignClient

  • contextld: If you want to create multiple Feign clients with the same name or URL, so that they point to the same server, but each client has a different custom configuration, you must use the contextId attribute to avoid name conflicts for these configurations

@FeignClient(contextId = "fooClient", name = "stores", configuration=FooConfiguration.class)
public interface FooClient {
    
    ...}

@FeignClient(contextId = "barClient", name = "stores", configuration=BarConfiguration.class)
public interface BarClient {
    
    ...}
  • fallback/fallbackFactory:

  • 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 @FeignClientmarked interface.

  • fallbackFactory: Factory class, used to generate fallback classes. Through this attribute, common fault-tolerant logic for each interface can be implemented to reduce duplicate code.

  • decode404: When a 404 error occurs, if this field is true, the decoder will be called to decode, otherwise an exception will be thrown.

  • Configuration: Feign configuration class can customize Feign's Encoder, Decoder, LogLevel, Contract, etc. OpenFeign provides the following objects for Feign by default (bean type bean name: class name):

  • Decoder feignDecoder : ResponseEntityDecoder

  • Encoder feignEncoder : SpringEncoder

  • Logger feignLogger : Slf4jLogger

  • Contract feignContract : SpringMvcContract

  • FeignBuilder feignBuilder : HystrixFeignBuilder

spring-cloud-starter-openfeign supports spring-cloud-starter-netflix-ribbon and spring-cloud-starter.loadbalancer. If Ribbon is in the classpath and enabled, the Client feignClient is LoadBalancerFeignClient. If SpringCloud LoadBalancer is in the classpath, Then use FeignBlockingLoadBalancerClient

By default, Spring Cloud OpenFeign does not provide the following bean objects for Feign, but these types of beans are still looked up from the application context to create Feign clients:

  • Logger.Level
  • Retryer
  • ErrorDecoder
  • Request.Options
  • Collection<RequestInterceptor>
  • SetterFactory
  • QueryMapEncoder

The above is @FeignClientconfigured through the configuration properties of the annotation. We can also configure it using the configuration file.

feign:
    client:
        config:
            feignName:
                connectTimeout: 5000
                readTimeout:5000
                loggerLevel: full
                errorDecoder: com.example.SimpleErrorDecoder
                retryer: com.example,SimpleRetryer
                requestInterceptors:
                    - com.example.FooRequestInterceptor
                    - com.example,BarRequestInterceptor
                decode404: false
                encoder: com.example.SimpleEncoder
                decoder: com.example.SimpleDecoder
                contract: com.example.SimpleContract

The default configuration can @EnableFeignClientsbe specified in the attribute defaultConfiguration, the difference is that this configuration will apply to all Feign clients

If you wish to use a configuration file to configure everything @FeignClient, you can create configuration properties with default Feign names, for example:

feign:
    client:
        config:
            default:
                connectTimeout: 5000
                readTimeout: 5000
                loggerLevel: basic

If you create both @Configurationthe bean and the config file, the config file will override the value, you can change the to false @Configurationif you want to change the priority to@Configurationfeign.client.default-to-properties


Feign parameter passing

The following server interface can be called through Get or Post requests and receives parameters

@RequestMapping("/test/testFeignWithParam")
public void testFeignWithParam(@RequestParam String name,
                               @RequestParam int age) {
    
    
    log.info("testFeignWithParam: name-{}, age-{}", name, age);
}

By splicing the parameters in the Url request as follows:

@FeignClient(name = "server-02", path = "server-02")
public interface Server02FeignClient {
    
    

    @GetMapping("/test/testFeignWithParam?name=zhanghsan&age=66")
    //@PostMapping("/test/testFeignWithParam?name=zhanghsan&age=66")
    void testFeignWithParam();
}

Use @RequestParamparameters passed as follows:

@FeignClient(name = "server-02", path = "server-02")
public interface Server02FeignClient {
    
    
    
    //@GetMapping("/test/testFeignWithParam")
    @PostMapping("/test/testFeignWithParam")
    void testFeignWithParam(@RequestParam("name") String name,
                            @RequestParam("age") int age);
}

You can also use OpenFeign's @QueryMapmapping of request entities as parameters, but since @QueryMapannotations are not compatible with Spring, OpenFeign provides equivalent @SpringQueryMapannotations .

@FeignClient(name = "server-02", path = "server-02")
public interface Server02FeignClient {
    
    
    
    //@GetMapping("/test/testFeignWithQueryMap")
    @PostMapping("/test/testFeignWithQueryMap")
    void testFeignWithQueryMap(@SpringQueryMap FeignParam param);
}

Guess you like

Origin blog.csdn.net/CSDN_handsome/article/details/133433803