Связанный
-
Spring Cloud Combat Series (1) — регистрация и обнаружение сервисов Eureka
-
Spring Cloud Combat Series (3) — Декларативное притворство клиента
-
Spring Cloud Combat Series (6) — Распределенный центр конфигурации Spring Cloud Config
-
Spring Cloud Combat Series (7) — отслеживание служебных ссылок Spring Cloud Sleuth
-
Spring Cloud Combat Series (8) — Мониторинг микросервисов Spring Boot Admin
-
Spring Cloud Combat Series (9) — Аутентификация и авторизация службы Spring Cloud OAuth 2.0
-
Практическая серия Spring Cloud (10) — Единый вход JWT и Spring Security OAuth
предисловие
В предыдущей статье я описал как пройтиRestTemplateСотрудничатьRibbonпотреблять услуги.FeignЯвляетсядекларативныйизHTTP поддельный клиент,поставкаориентированный на интерфейсизHTTP Звонок клиентапрограммирование. В этой статье далее объясняется, как пройтиFeignпотреблять услуги.
-
FeignПросто создайтеинтерфейси предоставитьаннотацияможно назвать. -
FeignимеютПодключаемыйФункция аннотации , вы можете использоватьFeignаннотацияа такжеJAX-RSаннотация. -
Feignслужба поддержкиПодключаемыйизКодера такжедекодер. -
Feignинтегрировано по умолчаниюRibbon, можно комбинировать сEurekaИспользуется в комбинации, по умолчанию реализованоБалансировка нагрузкиЭффект.
текст
1. Создайте модуль контракта на обслуживание
Создаватьservice-contractпроектModule, после созданияpom.xmlследующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>io.ostenant.github.springcloud</groupId>
<artifactId>service-contract</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>service-contract</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.ostenant.github.springcloud</groupId>
<artifactId>service-contract</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
существуетservice-contractопределено вбизнес-интерфейси связанные с нимиDTOОбъекты следующие:
User.java
public class User implements Serializable {
private String name;
private int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public void getName() {
return this.name;
}
public String setName() {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
}
UserContract.java
UserContractОпределенныйUserВсякое поведение есть использование@FeignClientаннотированныйДекларативный интерфейс службы. в,@FeignClientизvalueуказанопоставщики услугизнаименование услуги.
@FeignClient("service-provider")
public interface UserContract {
@PostMapping("/user")
void add(@RequestBody User user);
@GetMapping("/user/{name}")
User findByName(@PathVariable String name);
@GetMapping("/users")
List<User> findAll();
}
запоставщики услуг, необходимо реализоватьUserContractметоды интерфейса; дляпотребители услуг, его можно вводить напрямуюUserContractтак какклиентская заглушкаиспользовать.
2. Создайте поставщика услуг
Создаватьservice-providerпроектModule, импортируется после созданияМодуль сервисного контрактазависимость,pom.xmlследующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>io.ostenant.github.springcloud</groupId>
<artifactId>service-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>service-provider</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.ostenant.github.springcloud</groupId>
<artifactId>service-contract</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
пройти черезаннотация @EnableEurekaClientпоказать себя одинEureka Client.
@SpringBootApplication
@EnableEurekaClient
@RestController
public class ServiceProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceProviderApplication.class, args);
}
}
создать классUserService,выполнитьUserContractКонкретный бизнес интерфейса предоставляется извнеUserСвязанныйHTTPоказание услуг.
@RestController
public class UserService implements UserContract {
private static final Set<User> userSet = new HashSet<>();
static {
userSet.add(new User("Alex", 28));
userSet.add(new User("Lambert", 32));
userSet.add(new User("Diouf", 30));
}
@Override
public void add(@RequestBody User user) {
userSet.add(user);
}
@Override
public User findByName(@PathVariable String name) {
return userSet.stream().filter(user -> {
return user.getName().equals(name);
}).findFirst();
}
@Override
public List<User> findAll() {
return new ArrayList<>(userSet);
}
}
существуетконфигурационный файлотмечено вРеестр услугадрес,application.ymlФайл конфигурации выглядит следующим образом:
spring:
active:
profiles: sp1 # sp2
---
spring:
profiles: sp1
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8770
spring:
application:
name: service-provider
---
spring:
profiles: sp2
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8771
spring:
application:
name: service-provider
соответственно сspring.profiles.active=sp1а такжеspring.profiles.active=sp2так какSpring Bootизпараметры команды запуска,существуетНомер порта 8770а также8771запускать2индивидуальныйпоставщики услугпример.
3. Создайте потребителя услуги
создать новый проектModule, по имениservice-consumer, в егоpomимпортируется в файлFeignизЗависит от запускаа такжеМодуль сервисного контракта, код показан ниже:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>io.ostenant.github.springcloud</groupId>
<artifactId>service-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>service-consumer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.ostenant.github.springcloud</groupId>
<artifactId>service-contract</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
конфигурационный файл в проектеapplication.ymlфайл, указанныйИмя приложениязаservice-consumer,Номер портаза8772,Адрес регистрации службызаhttp://localhost:8761/eureka/, код показан ниже:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8772
spring:
application:
name: service-feign
В стартовом классе приложенияServiceConsumerApplicationдобавить@EnableFeignClientsАннотация включенаFeignфункция.
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ServiceConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceConsumerApplication.class, args);
}
}
определитьUserControllerконтроллер для вызовапоставщики услугпредоставляемые услуги иоткликвнешний интерфейс.
@RestController
public class UserController {
@Autowired
private UserContract userContract;
@PostMapping("/user")
public void add(@RequestBody User user) {
userContract.add(user);
}
@GetMapping("/user/{name}")
public User findByName(@PathVariable String name) {
return userContract.findByName(name);
}
@GetMapping("/users")
public List<User> findAll() {
return userContract.findAll();
}
}
существуетслой управления UserControllerпредставлятьFeignинтерфейс, через@FeignClient(наименование услуги), чтобы указать, что вызываетсяСлужить.
запускатьпотребители услугприложение, доступhttp://localhost:8772/usersтестовое заданиепотребители услугполучить доступ к подключению, содержание ответа:
[
{
"name": "Alex",
"age": 28
},
{
"name": "Lambert",
"age": 32
},
{
"name": "Diouf",
"age": 30
}
]
4. Процесс реализации исходного кода Feign
В основном,Feignизреализация исходного кодаПроцесс выглядит следующим образом:
-
сначала через
@EnableFeignClientsАннотация включенаFeignClientфункция. только этоаннотациясуществует только при запуске программызапускать@FeignClientаннотацияизсканирование пакетов. -
поставщики услугреализация на основе
Feignизконтрактный интерфейс, И вконтрактный интерфейсдобавить выше@FeignClientаннотация. -
потребители услугПосле запускасканирование пакетовоперация, сканировать все
@FeignClientизаннотацияclass и внедрить эту информацию вSpringв контексте. -
когдаинтерфейсметод вызывается
JDKизиграет рольдля создания конкретныхRequestTemplateобъект шаблона. -
согласно с
RequestTemplateрегенерацияHTTPпросилRequestобъект. -
RequestВозражатьClientобрабатывать, чтоClientв линиюПлатформа веб-запросоввозможноHTTPURLConnection,HttpClientа такжеOkHttp. -
наконец
Clientзаключен вLoadBalanceClientкласс, этот класс объединяетRibbonЗаканчиватьБалансировка нагрузкиФункция.
Ссылаться на
- Фан Чжипэн «Глубокое понимание Spring Cloud и построения микросервисов»
Добро пожаловать в технический публичный аккаунт: Zero One Technology Stack
Эта учетная запись будет продолжать делиться сухими товарами серверных технологий, включая основы виртуальных машин, многопоточное программирование, высокопроизводительные фреймворки, асинхронное ПО, промежуточное ПО для кэширования и обмена сообщениями, распределенные и микросервисы, материалы для обучения архитектуре и расширенные учебные материалы и статьи.