Practical application: two usage postures of Spring Cloud Feign

Article directory

  • Overview
  • Create a service registry based on Eureka
  • Create a service provider
  • Create a Feign-based service consumer
  • Abstract a public API service
  • Service provider/consumer before transformation

Overview

Recently, I learned Spring Cloud in combination with some other people’s open source projects. Among them, Feign, a very convenient tool for service consumption, reminds me deeply. Although there are too many demos and examples on the Internet, most of them are scattered. This article focuses on recording some usage postures of the declarative client Feign.

Create a service registry based on Eureka

Three steps to get it done:

  • Construction

Create a SpringBoot project named eureka_server, and add the corresponding dependencies in pom.xml

 <!--Import Eureka Server dependency-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
  • Change the main class

Modify the main class of the application and add the @EnableEurekaServer annotation

@SpringBootApplication
// @EnableEurekaServer The startup class of the server, which can accept others to register
@EnableEurekaServer
public class EurekaServer7001 {<!-- -->
    public static void main(String[] args) {<!-- -->
        SpringApplication.run(EurekaServer.class, args);
    }
}
  • Add configuration
    Configure the application.properties file as follows:
server:
  port: 7001

# Eureka configuration
eureka:
 instance:
   # The instance name of the Eureka server
   hostname: eureka7001.com
 client:
   #Indicates whether to register yourself with the eureka registration center (this module itself is a server, so it is not required)
   register-with-eureka: false
   If #fetch-registry is false, it means that it is a registry, and if it is a client, it is true.
   fetch-registry: false
   service-url:
     # stand-alone
    #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    # Cluster (association): 7001 is associated with 7002, 7003
    defaultZone: http://eureka7002.com:7002/eureka/, http://eureka7003.com:7003/eureka/
  • Start Service Registry

Browser access:

There are no services registered yet.

Create a service provider

  • Construction

Create a SpringBoot project named springcloud-provider-dept, and add the corresponding dependencies in pom.xml:

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
         <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
  • Change the main class

Add @EnableDiscoveryClient annotation

@SpringBootApplication
@EnableEurekaClient //Enable the Eureka client annotation, and automatically register the service with the registration center after the service starts
@EnableDiscoveryClient //Enable the annotation of the service discovery client, which can be used to obtain some configuration information and obtain specific microservices.
public class DeptProvider_8001 {<!-- -->
    public static void main(String[] args) {<!-- -->
        SpringApplication.run(DeptProvider_8001.class, args);
    }
}
  • Add controller DateServiceController
@RestController
@Slf4j
public class DateServiceController {<!-- -->

    @GetMapping("/test")
    public String test(@RequestParam String param){<!-- -->
        return "hello " + param;
    }
}
  • Configure the application.properties file
server:
  port: 8001
spring:
  application:
    name: springcloud-provider-dept #Project name
#eurekaconfiguration
eureka:
  client:

    #Indicates whether to register yourself with the eureka registration center, true means to register, false means not to register
    register-with-eureka: true
    If #fetch-registry is false, it means that it is a registry, and if it is a client, it is true.
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/, http://eureka7002.com:7002/eureka/, http://eureka7003.com:7003/eureka/, #Configure service registry address
  instance:
    instance-id: springcloud-provider-dept-8001 #Modify the default description information on Eureka
    prefer-ip-address: true #display ip
  • start project

The browser accesses the service registration center, and we find that the service provider springcloud-provider-dept has been registered on eureka_server:

At the same time, the browser visits: http://localhost:8001/test?param=world, you can test the interface provided by the service provider springcloud-provider-dept to work normally


Next we create the service consumer, it’s time for Feign to debut!

Create a service consumer based on Feign

  • Create a SpringBoot project named springcloud-consumer-dept, and add the corresponding dependencies in pom.xml
 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--Eureka: Ribbon needs to get what to get from the Eureka service center -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--Feign's dependency-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
    </dependencies>
        <!--Introduce monitoring function-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.6.3</version>
            <scope>test</scope>
        </dependency>
  • Modify the application main class

It is mainly to add some annotations about the Feign client

After the Ribbon and Eureka are integrated, the client can call directly without caring about the IP address and port number
@SpringBootApplication
@EnableEurekaClient //Enable the Eureka client annotation, and automatically register the service with the registration center after the service starts
// Feign client annotation, and specify the package to be scanned and the configuration interface DeptClientService
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {<!-- -->"com.dhx.springcloud"})
public class FeignDeptConsumer_80 {<!-- -->
    public static void main(String[] args) {<!-- -->
        SpringApplication.run(FeignDeptConsumer_80.class, args);
    }
}
  • Create a Feign client interface: DateServiceFeignClientInterface

Obviously, it points to the service provider in the way of @FeignClient(value="SPRINGCLOUD-PROVIDER-DEPT") declared internally, and the interface method implements the actual call to the service provider interface

// @FeignClient: microservice client annotation, value: specify the name of the microservice, so that the Feign client can directly find the corresponding microservice
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
public interface DateServiceFeignClientInterface {<!-- -->

    @GetMapping("/test")
    public String test(@RequestParam("param") String param);
}
  • Create a controller: DateServiceFeignController

Note that this is the Rest interface provided by the service consumer

@RestController
public class DateServiceFeignController {<!-- -->

    @Autowired
    private DateServiceFeignClientInterface dateServiceFeignClientInterface;

    @GetMapping("/consumer/date")
    public String test(@RequestParam("param") String param){<!-- -->
       return dateServiceFeignClientInterface.test(param);
    }

}
  • Configure application.properties
server:
  port: 8090

#Spring configuration
spring:
  application:
    name: springcloud-consumer-dept #project name
  main:
    allow-bean-definition-overriding: true
# Eureka configuration
eureka:
  client:
    #Indicates whether to register yourself with the eureka registration center, true means to register, false means not to register
    register-with-eureka: true
    service-url: # Randomly select one of the three registration centers to visit
      defaultZone: http://eureka7001.com:7001/eureka/ #Configure service registration center address
  • Start the service consumer

Let’s go to the service registration center first and find that service consumers have also registered:


Then our browser accesses the Rest interface provided by the service consumer: http://localhost:8090/consumer/date?param=zhangsan


In this way, we get the interface data given by the service provider through the Feign client of the service consumer.

The above is the first usage posture of the declarative client Feign, and it is also a common method, which is common in many Demos.

Abstract a public API service

  • Create a normal Maven project: service_provider_api

  • Create a public interface: DateService

 public interface DateService{<!-- -->
    @GetMapping("/api/test")
    public String test(@RequestParam("param") String param);
}

Service provider/consumer before transformation

  • Add a new Feign client interface to the service consumer springcloud-consumer-dept project
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
@Component
public interface DateServiceFeignClientInterface2 extendsDateService {<!-- -->


    @GetMapping("/test")
    public String test(@RequestParam("param") String param);
}
  • And add a new controller DateServiceFeignController2 in the springcloud-consumer-dept project
@RestController
public class DateServiceFeignController {<!-- -->

    @Autowired
    private DateServiceFeignClientInterface2 dateServiceFeignClientInterface2;

    @GetMapping("/consumer/date")
    public String test(@RequestParam("param") String param){<!-- -->
       return dateServiceFeignClientInterface2.test(param);
    }

}
  • Implement our DateService interface in the public api project service_provider_api in the service provider springcloud-provider-dept project, and give the actual logic
@RestController
public class DateServiceFeignController2 implements DateService
{<!-- -->

        @Override
    public String consumer(@RequestParamStringparam){<!-- -->
        Datenow=new Date();
        SimpleDateFormat SimpleDateFormat = NewsimpleDateFormat (\ "today is " + \ "yyyy year MM month DD day E KK point mm points");
        StringnowTime=simpleDateFormat. format(now);
        return "hello again " + param + ", " + nowTime;
    }

}
  • Start the three projects eureka_server, springcloud-provider-dept, springcloud-consumer-dept in turn

Browser access: http://localhost:8001/test?param=world23323

When using feign’s inheritance feature, the definition of the service interface can be separated from the service consumer to form an independent api project, so that the interface definition and dependency sharing can be easily realized, and there is no need to copy and paste the interface for binding. Of course, this The problem with this approach is that it may lead to an increase in the coupling between the service provider and the service consumer. At this time, if the service provider modifies an interface definition, the service consumer may have to change accordingly, which will bring some pitfalls.