原先ribbon代碼存在的問(wèn)題:不規(guī)范,風(fēng)格不統(tǒng)一匀们,維護(hù)性比較差
什么是Feign
- SpringCloud提供的偽http客戶端(本質(zhì)還是用http)塞赂,封裝了Http調(diào)用流程,更適合面向接口化,用Java接口注解的方式調(diào)用Http請(qǐng)求
- 不用像Ribbon中通過(guò)封裝HTTP請(qǐng)求報(bào)文的方式調(diào)用 Feign默認(rèn)集成了Ribbon
- Nacos支持Feign,可以直接集成實(shí)現(xiàn)負(fù)載均衡的效果
Ribbon和feign兩個(gè)的區(qū)別和選擇
- 選擇feign
- 默認(rèn)集成了ribbon
- 寫(xiě)起來(lái)更加思路清晰和方便
- 采用注解方式進(jìn)行配置,配置熔斷等方式方便
官方文檔
https://spring.io/projects/spring-cloud-openfeign
接入 Open-feign (相關(guān)代碼完整版放在本文最后部分)
在之前章節(jié)的基礎(chǔ)上酌住,online-edu\pom.xml增加依賴(lài):
<!-- 負(fù)載均衡-openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>4.1.3</version>
</dependency>
online-edu-order-service/pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
online-edu-order-service/src/main/java/org/online_edu/OrderApplication.java
package org.online_edu;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication()
@MapperScan("org.online_edu.dao")
// 開(kāi)啟服務(wù)發(fā)現(xiàn)
@EnableDiscoveryClient
// 開(kāi)啟openfeign負(fù)載均衡支持
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
online-edu-order-service/src/main/java/org/online_edu/controller/VideoOrderController.java
package org.online_edu.controller;
import org.online_edu.domain.Video;
import org.online_edu.domain.VideoOrder;
import org.online_edu.service.VideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
@RequestMapping("/api/v1/video_order")
public class VideoOrderController {
/**
* 服務(wù)對(duì)象
*/
@Autowired
private VideoService videoService;
@RequestMapping("/find_by_id")
public Object save(@RequestParam(name = "videoId") int videoId) {
Video video = videoService.findById(videoId);
VideoOrder videoOrder = new VideoOrder();
if (video != null) {
videoOrder.setServeInfo(video.getServeInfo());
videoOrder.setVideoId(video.getId());
videoOrder.setVideoTitle(video.getTitle());
videoOrder.setCreateTime(new Date());
}
return videoOrder;
}
}
online-edu-order-service/src/main/java/org/online_edu/service/VideoService.java
package org.online_edu.service;
import org.online_edu.domain.Video;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "online-edu-video-service")
public interface VideoService {
@GetMapping(value = "/api/v1/video/find_by_id")
Video findById(@RequestParam("videoId") int videoId);
}
online-edu-video-service/src/main/java/org/online_edu/controller/VideoController.java
package org.online_edu.controller;
import jakarta.servlet.http.HttpServletRequest;
import org.online_edu.domain.Video;
import org.online_edu.service.VideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("api/v1/video")
public class VideoController {
@Autowired
private VideoService videoService;
@RequestMapping("/find_by_id")
public Video findById(@RequestParam(name = "videoId") int videoId, HttpServletRequest request) {
Video video = videoService.findById(videoId);
// 拿到服務(wù)端的id+端口
video.setServeInfo(request.getServerName() + ":" + request.getServerPort());
return video;
}
}
完整代碼如下:
online-edu\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>
<groupId>org.online_edu</groupId>
<artifactId>online-edu</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>online-edu-common</module>
<module>online-edu-video-service</module>
<module>online-edu-user-service</module>
<module>online-edu-order-service</module>
<module>online-edu-generator</module>
</modules>
<!-- 一般來(lái)說(shuō)父級(jí)項(xiàng)目的packaging都為pom伴挚,packaging默認(rèn)類(lèi)型jar類(lèi)型-->
<packaging>pom</packaging>
<properties>
<java.version>21</java.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot-dependencies.version>3.3.3</spring-boot-dependencies.version>
<spring-cloud-dependencies.version>2023.0.3</spring-cloud-dependencies.version>
<spring-cloud-alibaba-dependencies.version>2023.0.1.2</spring-cloud-alibaba-dependencies.version>
<org.mapstruct.version>1.6.0</org.mapstruct.version>
</properties>
<!--鎖定版本-->
<dependencyManagement>
<dependencies>
<!-- **************************** 分布式核心 **************************** -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-alibaba-dependencies -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<version>4.1.4</version>
</dependency>
<!-- 負(fù)載均衡-openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>4.1.3</version>
</dependency>
<!-- **************************** 分布式核心 **************************** -->
<!-- **************************** 數(shù)據(jù)庫(kù)依賴(lài) **************************** -->
<!-- MyBatis-Plus啟動(dòng)器,增強(qiáng)版MyBatis沦辙,提供更高效的操作和動(dòng)態(tài)SQL能力 -->
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-spring-boot3-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.7</version>
</dependency>
<!-- PostgreSQL的JDBC驅(qū)動(dòng) -->
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.3</version>
</dependency>
<!-- Druid組件 -->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-3-starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.23</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<!-- **************************** 數(shù)據(jù)庫(kù)依賴(lài) **************************** -->
<!-- **************************** 工具類(lèi) **************************** -->
<!-- 一個(gè)用于在 Java Bean 之間轉(zhuǎn)換的代碼生成工具夫植。-->
<!-- 官網(wǎng):https://mapstruct.org/ -->
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct-processor -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<!-- commons-lang3: 通用的、可復(fù)用的 Java 組件油讯,已其他包引入-->
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<!--(Map详民、List、Set集合全覆蓋)集合開(kāi)發(fā)工具-->
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.5.0-M2</version>
</dependency>
<!-- Java增強(qiáng)器陌兑,像Java Next版本-->
<!-- 集合 [collections] 沈跨、緩存 [caching] 、原生類(lèi)型支持 [primitives support] 兔综、
并發(fā)庫(kù) [concurrency libraries] 饿凛、通用注解 [common annotations] 狞玛、
字符串處理 [string processing] 、I/O 等等-->
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.3.0-jre</version>
</dependency>
<!-- Java必備工具庫(kù) -->
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.32</version>
</dependency>
<!-- JSON序列化和反序列化 :已由別的包引入-->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<!-- **************************** 工具類(lèi) **************************** -->
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
online-edu-order-service/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.online_edu</groupId>
<artifactId>online-edu</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>online-edu-order-service</artifactId>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.online_edu</groupId>
<artifactId>online-edu-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>-->
<!-- </dependency>-->
<!-- 添加nacos客戶端——服務(wù)注冊(cè) -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
</dependency>
<!-- PostgreSQL的JDBC驅(qū)動(dòng) -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
運(yùn)行:
Post傳輸對(duì)象
online-edu-order-service/src/main/java/org/online_edu/controller/VideoOrderController.java
@PostMapping("/save")
public void save(@RequestBody Video video) {
videoService.save(video);
}
online-edu-order-service/src/main/java/org/online_edu/service/VideoService.java
@PostMapping(value = "/api/v1/video/save")
int save(@RequestBody Video video);
online-edu-video-service/src/main/java/org/online_edu/controller/VideoController.java
/**
* 測(cè)試 feign 調(diào)用 使用post方法傳輸對(duì)象
*
* @param video
* @return
*/
@PostMapping("/save")
public Object save(@RequestBody Video video) {
int rows = videoService.save(video);
System.out.println(video.getTitle());
HashMap<String, Object> map = new HashMap<>();
map.put("row", rows);
return map;
}
online-edu-video-service/src/main/java/org/online_edu/service/VideoService.java
int save(Video video);
online-edu-video-service/src/main/java/org/online_edu/service/impl/VideoServiceImpl.java
/**
* @param video
* @return
*/
@Override
public int save(Video video) {
return 1;
}
運(yùn)行:
Header中的Content-Type
設(shè)置成application/json