当前位置: 首页 > news >正文

OpenFeign 万字教程详解

OpenFeign 万字教程详解

目录

  • 一、概述

    • 1.1.OpenFeign是什么?
    • 1.2.OpenFeign能干什么
    • 1.3.OpenFeign和Feign的区别
    • 1.4.@FeignClient
  • 二、OpenFeign使用

    • 2.1.OpenFeign 常规远程调用
    • 2.2.OpenFeign 微服务使用步骤
    • 2.3.OpenFeign 超时控制
    • 2.4.OpenFeign 日志打印
    • 2.5.OpenFeign 添加Header
    • 2.6.手动创建 Feign 客户端
    • 2.7.Feign 继承支持
    • 2.8.Feign 和Cache集成
    • 2.9.OAuth2 支持

一、概述

1.1.OpenFeign是什么?

Feign是一个声明式的Web服务客户端(Web服务客户端就是Http客户端),让编写Web服务客户端变得非常容易,只需创建一个接口并在接口上添加注解即可。

cloud官网介绍Feign: https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/

OpenFeign源码: https://github.com/OpenFeign/feign

1.2.OpenFeign能干什么

Java当中常见的Http客户端有很多,除了Feign,类似的还有Apache 的 HttpClient 以及OKHttp3,还有SpringBoot自带的RestTemplate这些都是Java当中常用的HTTP 请求工具。

什么是Http客户端?

当我们自己的后端项目中 需要 调用别的项目的接口的时候,就需要通过Http客户端来调用。在实际开发当中经常会遇到这种场景,比如微服务之间调用,除了微服务之外,可能有时候会涉及到对接一些第三方接口也需要使用到 Http客户端 来调用 第三方接口。

所有的客户端相比较,Feign更加简单一点,在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),即可完成对服务提供方的接口绑定。

1.3.OpenFeign和Feign的区别
Feign:

Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务。

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-feign</artifactId>
</dependency> 
OpenFeign:

OpenFeign是Spring Cloud 在Feign的基础上支持了SpringMVC的注解,如@RequesMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

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

Feign是在2019就已经不再更新了,通过maven网站就可以看出来,随之取代的是OpenFeign,从名字上就可以知道,他是Feign的升级版。

1.4.@FeignClient

使用OpenFeign就一定会用到这个注解,@FeignClient属性如下:

  • **name:**指定该类的容器名称,类似于@Service(容器名称)
  • url: url一般用于调试,可以手动指定@FeignClient调用的地址
  • *decode404:*当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
  • configuration: Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
  • fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
  • fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码
  • path: 定义当前FeignClient的统一前缀,当我们项目中配置了server.context-path,server.servlet-path时使用
下面这两种本质上没有什么区别:

他们都是一个作用就是将FeignClient注入到spring容器当中

@FeignClient(name = "feignTestService", url = "http://localhost/8001")
public interface FeignTestService {
}
@Component
@FeignClient(url = "http://localhost/8001")
public interface PaymentFeignService{
}

远程调用接口当中,一般我们称提供接口的服务为提供者,而调用接口的服务为消费者。而OpenFeign一定是用在消费者上。

二、OpenFeign使用

2.1.OpenFeign 常规远程调用

所谓常规远程调用,指的是对接第三方接口,和第三方并不是微服务模块关系,所以肯定不可能通过注册中心来调用服务。

第一步:导入OpenFeign的依赖

第二步:启动类需要添加@EnableFeignClients

第三步:提供者的接口

@RestController
@RequestMapping("/test")
public class FeignTestController {@GetMapping("/selectPaymentList")public CommonResult<Payment> selectPaymentList(@RequestParam int pageIndex, @RequestParam int pageSize) {System.out.println(pageIndex);System.out.println(pageSize);Payment payment = new Payment();payment.setSerial("222222222");return new CommonResult(200, "查询成功, 服务端口:" + payment);}@GetMapping(value = "/selectPaymentListByQuery")public CommonResult<Payment> selectPaymentListByQuery(Payment payment) {System.out.println(payment);return new CommonResult(200, "查询成功, 服务端口:" + null);}@PostMapping(value = "/create", consumes = "application/json")public CommonResult<Payment> create(@RequestBody Payment payment) {System.out.println(payment);return new CommonResult(200, "查询成功, 服务端口:" + null);}@GetMapping("/getPaymentById/{id}")public CommonResult<Payment> getPaymentById(@PathVariable("id") String id) {System.out.println(id);return new CommonResult(200, "查询成功, 服务端口:" + null);}
}

第四步:消费者调用提供者接口

@FeignClient(name = "feignTestService", url = "http://localhost/8001")
public interface FeignTestService {@GetMapping(value = "/payment/selectPaymentList")CommonResult<Payment> selectPaymentList(@RequestParam int pageIndex, @RequestParam int pageSize);@GetMapping(value = "/payment/selectPaymentListByQuery")CommonResult<Payment> selectPaymentListByQuery(@SpringQueryMap Payment payment);@PostMapping(value = "/payment/create", consumes = "application/json")CommonResult<Payment> create(@RequestBody Payment payment);@GetMapping("/payment/getPaymentById/{id}")CommonResult<Payment> getPaymentById(@PathVariable("id") String id);
}
@SpringQueryMap注解

spring cloud项目使用feign的时候都会发现一个问题,就是get方式无法解析对象参数。其实feign是支持对象传递的,但是得是Map形式,而且不能为空,与spring在机制上不兼容,因此无法使用。spring cloud在2.1.x版本中提供了@SpringQueryMap注解,可以传递对象参数,框架自动解析。

2.2.OpenFeign 微服务使用步骤

微服务之间使用OpenFeign,肯定是要通过注册中心来访问服务的。提供者将自己的ip+端口号注册到注册中心,然后对外提供一个服务名称,消费者根据服务名称去注册中心当中寻找ip和端口。

第一步:导入OpenFeign的依赖

第二步:启动类需要添加@EnableFeignClients

第三步:作为消费者,想要调用提供者需要掌握以下

CLOUD-PAYMENT-SERVICE是提供者的服务名称。消费者要想通过服务名称来调用提供者,那么就一定需要配置注册中心当中的服务发现功能。假如提供者使用的是Eureka,那么消费者就需要配置Eureka的服务发现,假如是consul就需要配置consul的服务发现。

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {@GetMapping(value = "/payment/get/{id}")CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}

第四步:提供者的接口,提供者可以是集群

@RestController
@Slf4j
public class PaymentController {@Autowiredprivate PaymentMapper paymentMapper;@Value("${server.port}")private String serverPort;@GetMapping(value = "/payment/get/{id}")public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {Payment payment = paymentMapper.selectById(id);log.info("*****查询结果:{}", payment);if (payment != null) {return new CommonResult(200, "查询成功, 服务端口:" + serverPort, payment);} else {return new CommonResult(444, "没有对应记录,查询ID: " + id + ",服务端口:" + serverPort, null);}}
}

第五步:然后我们启动注册中心以及两个提供者服务,启动后浏览器我们进行访问

他不仅限于和Eureka注册中心使用,我这里是基于Eureka来进行使用的,需要了解Eureka注册中心的搭建可以看这篇文章:

https://blog.csdn.net/weixin_43888891/article/details/125325794

使用OpenFeign,假如是根据服务名称调用,OpenFeign他本身就集成了ribbon自带负载均衡。

图片

2.3.OpenFeign 超时控制

第一步:提供方接口,制造超时场景

@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeOut() {System.out.println("*****paymentFeignTimeOut from port: " + serverPort);//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}return serverPort;
}

第二步:消费方接口调用

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService{@GetMapping(value = "/payment/feign/timeout")String paymentFeignTimeOut();
}

当消费方调用提供方时候,OpenFeign默认等待1秒钟,超过后报错

图片

第三步:在消费者添加如下配置

#设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间ReadTimeout: 5000#指的是建立连接后从服务器读取到可用资源所用的时间ConnectTimeout: 5000

在openFeign高版本当中,我们可以在默认客户端和命名客户端上配置超时。OpenFeign 使用两个超时参数:

  • connectTimeout:防止由于服务器处理时间长而阻塞调用者。
  • readTimeout:从连接建立时开始应用,在返回响应时间过长时触发。
2.4.OpenFeign 日志打印

Feign 提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解 Feign 中 Http 请求的细节。

说白了就是对Feign接口的调用情况进行监控和输出

日志级别:

  • NONE:默认的,不显示任何日志;
  • BASIC:仅记录请求方法、URL、响应状态码及执行时间;
  • HEADERS:除了 BASIC 中定义的信息之外,还有请求和响应的头信息;
  • FULL:除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。

配置日志Bean:

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class FeignConfig {@BeanLogger.Level feignLoggerLevel() {return Logger.Level.FULL;}
}

YML文件里需要开启日志的Feign客户端

logging:level:# feign日志以什么级别监控哪个接口com.gzl.cn.service.PaymentFeignService: debug

后台日志查看:

图片

2.5.OpenFeign 添加Header

以下提供了四种方式:

  1. 在@RequestMapping中添加,如下:
@FeignClient(name="custorm",fallback=Hysitx.class)
public interface IRemoteCallService {@RequestMapping(value="/custorm/getTest",method = RequestMethod.POST,headers = {"Content-Type=application/json;charset=UTF-8"})List<String> test(@RequestParam("names") String[] names);
}
  1. 在方法参数前面添加@RequestHeader注解,如下:
@FeignClient(name="custorm",fallback=Hysitx.class)
public interface IRemoteCallService {@RequestMapping(value="/custorm/getTest",method = RequestMethod.POST,headers = {"Content-Type=application/json;charset=UTF-8"})List<String> test(@RequestParam("names")@RequestHeader("Authorization") String[] names);
}

设置多个属性时,可以使用Map,如下:

@FeignClient(name="custorm",fallback=Hysitx.class)
public interface IRemoteCallService {@RequestMapping(value="/custorm/getTest",method = RequestMethod.POST,headers = {"Content-Type=application/json;charset=UTF-8"})List<String> test(@RequestParam("names") String[] names, @RequestHeader MultiValueMap<String, String> headers);
}
  1. 使用@Header注解,如下:
@FeignClient(name="custorm",fallback=Hysitx.class)
public interface IRemoteCallService {@RequestMapping(value="/custorm/getTest",method = RequestMethod.POST)@Headers({"Content-Type: application/json;charset=UTF-8"})List<String> test(@RequestParam("names") String[] names);
}
  1. 实现RequestInterceptor接口(拦截器),如下:

只要通过FeignClient访问的接口都会走这个地方,所以使用的时候要注意一下。

@Configuration
public class FeignRequestInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate temp) {temp.header(HttpHeaders.AUTHORIZATION, "XXXXX");}
}
2.6.手动创建 Feign 客户端

@FeignClient无法支持同一service具有多种不同配置的FeignClient,因此,在必要时需要手动build FeignClient。

@FeignClient(value = “CLOUD-PAYMENT-SERVICE”)

以这个为例,假如出现两个服务名称为CLOUD-PAYMENT-SERVICE的FeignClient,项目直接会启动报错,但是有时候我们服务之间调用的地方较多,不可能将所有调用都放到一个FeignClient下,这时候就需要自定义来解决这个问题!

官网当中也明确提供了自定义FeignClient,以下是在官网基础上对自定义FeignClient的一个简单封装,供参考!

首先创建FeignClientConfigurer类,这个类相当于build FeignClient的工具类

import feign.*;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.slf4j.Slf4jLogger;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.context.annotation.Import;@Import(FeignClientsConfiguration.class)
public class FeignClientConfigurer {private Decoder decoder;private Encoder encoder;private Client client;private Contract contract;public FeignClientConfigurer(Decoder decoder, Encoder encoder, Client client, Contract contract) {this.decoder = decoder;this.encoder = encoder;this.client = client;this.contract = contract;}public RequestInterceptor getUserFeignClientInterceptor() {return new RequestInterceptor() {@Overridepublic void apply(RequestTemplate requestTemplate) {// 添加header}};}public <T> T buildAuthorizedUserFeignClient(Class<T> clazz, String serviceName) {return getBasicBuilder().requestInterceptor(getUserFeignClientInterceptor())//默认是Logger.NoOpLogger.logger(new Slf4jLogger(clazz))//默认是Logger.Level.NONE(一旦手动创建FeignClient,全局配置的logger就不管用了,需要在这指定).logLevel(Logger.Level.FULL).target(clazz, buildServiceUrl(serviceName));}private String buildServiceUrl(String serviceName) {return "http://" + serviceName;}protected Feign.Builder getBasicBuilder() {return Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract);}
}

使用工具类的方法创建多个FeignClient配置

import com.gzl.cn.service.FeignTest1Service;
import feign.Client;
import feign.Contract;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class FeignClientConfiguration extends FeignClientConfigurer {public FeignClientConfiguration(Decoder decoder, Encoder encoder, Client client, Contract contract) {super(decoder, encoder, client, contract);}@Beanpublic FeignTest1Service feignTest1Service() {return super.buildAuthorizedUserFeignClient(FeignTest1Service.class, "CLOUD-PAYMENT-SERVICE");}// 假如多个FeignClient在这里定义即可
}

其中,super.buildAuthorizedUserFeignClient()方法中,第一个参数为调用别的服务的接口类,第二个参数为被调用服务在注册中心的service-id。

public interface FeignTest1Service {@GetMapping(value = "/payment/get/{id}")CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}

使用的时候正常注入使用即可

@Resource
private FeignTest1Service feignTest1Service;
2.7.Feign 继承支持

Feign 通过单继承接口支持样板 API。这允许将常用操作分组到方便的基本接口中。

UserService.java

public interface UserService {@RequestMapping(method = RequestMethod.GET, value ="/users/{id}")User getUser(@PathVariable("id") long id);
}

UserResource.java

@RestController
public class UserResource implements UserService {
}

UserClient.java

package project.user;@FeignClient("users")
public interface UserClient extends UserService {}
2.8.Feign 和Cache集成

如果@EnableCaching使用注解,CachingCapability则创建并注册一个 bean,以便您的 Feign 客户端识别@Cache*其接口上的注解:

public interface DemoClient {@GetMapping("/demo/{filterParam}")@Cacheable(cacheNames = "demo-cache", key = "#keyParam")String demoEndpoint(String keyParam, @PathVariable String filterParam);
}

您还可以通过 property 禁用该功能feign.cache.enabled=false

注意feign.cache.enabled=false只有在高版本才有

2.9.OAuth2 支持

可以通过设置以下标志来启用 OAuth2 支持:

feign.oauth2.enabled=true

当标志设置为 true 并且存在 oauth2 客户端上下文资源详细信息时,将OAuth2FeignRequestInterceptor创建一个类 bean。在每个请求之前,拦截器解析所需的访问令牌并将其作为标头包含在内。有时,当为 Feign 客户端启用负载平衡时,您可能也希望使用负载平衡来获取访问令牌。

为此,您应该确保负载均衡器位于类路径 (spring-cloud-starter-loadbalancer) 上,并通过设置以下标志显式启用 OAuth2FeignRequestInterceptor 的负载均衡:

feign.oauth2.load-balanced=true

ring keyParam, @PathVariable String filterParam);
}


您还可以通过 property 禁用该功能feign.cache.enabled=false> ❝
>
> 注意feign.cache.enabled=false只有在高版本才有
>
> ❞#### 2.9.OAuth2 支持可以通过设置以下标志来启用 OAuth2 支持:

feign.oauth2.enabled=true


当标志设置为 true 并且存在 oauth2 客户端上下文资源详细信息时,将OAuth2FeignRequestInterceptor创建一个类 bean。在每个请求之前,拦截器解析所需的访问令牌并将其作为标头包含在内。有时,当为 Feign 客户端启用负载平衡时,您可能也希望使用负载平衡来获取访问令牌。为此,您应该确保负载均衡器位于类路径 (spring-cloud-starter-loadbalancer) 上,并通过设置以下标志显式启用 OAuth2FeignRequestInterceptor 的负载均衡:

feign.oauth2.load-balanced=true


注意feign.cache.enabled=false只有在高版本才有

相关文章:

OpenFeign 万字教程详解

OpenFeign 万字教程详解 目录 一、概述 1.1.OpenFeign是什么&#xff1f;1.2.OpenFeign能干什么1.3.OpenFeign和Feign的区别1.4.FeignClient 二、OpenFeign使用 2.1.OpenFeign 常规远程调用2.2.OpenFeign 微服务使用步骤2.3.OpenFeign 超时控制2.4.OpenFeign 日志打印2.5.O…...

全自动双轴晶圆划片机:半导体制造的关键利器

随着科技的飞速发展&#xff0c;半导体行业正以前所未有的速度向前迈进。在这个过程中&#xff0c;全自动双轴晶圆划片机作为一种重要的设备&#xff0c;在半导体晶圆、集成电路、QFN、发光二极管、miniLED、太阳能电池、电子基片等材料的划切过程中发挥着举足轻重的作用。 全自…...

Android Studio 安装和使用

前些天&#xff0c;打开了几年前的一个Android Studio app项目&#xff0c;使用安卓虚拟机仿真app崩溃&#xff0c;怀疑是不是中间升级过Android Studio导致异常的&#xff0c;马上脑子一热卸载了&#xff0c;结果上次踩过的坑&#xff0c;一个没少又踩一次&#xff0c;谨以此文…...

【已解决】Java中,判断:集合中是否包含指定元素(模糊匹配)比如权限中的user:list或者是user:*这种判断

背景描述 在工作中&#xff0c;有时候&#xff0c;我们需要对list中是否包含了指定元素进行判断&#xff0c;但是&#xff0c;有时候又需要支持模糊匹配&#xff0c;这个时候怎么办呢&#xff1f; 比如权限&#xff0c;我们知道&#xff0c;权限不仅可以配置完整的路径&#…...

【基于激光雷达的路沿检测用于自动驾驶的真值标注】

文章目录 概要主要贡献内容概述实验小结 概要 论文地址&#xff1a;https://arxiv.org/pdf/2312.00534.pdf 路沿检测在自动驾驶中扮演着重要的角色&#xff0c;因为它能够帮助车辆感知道可行驶区域和不可行驶区域。为了开发和验证自动驾驶功能&#xff0c;标注的数据是必不可…...

【Spring实战】配置多数据源

文章目录 1. 配置数据源信息2. 创建第一个数据源3. 创建第二个数据源4. 创建启动类及查询方法5. 启动服务6. 创建表及做数据7. 查询验证8. 详细代码总结 通过上一节的介绍&#xff0c;我们已经知道了如何使用 Spring 进行数据源的配置以及应用。在一些复杂的应用中&#xff0c;…...

DevOps系列文章 : 使用dpkg命令打deb包

创建一个打包的目录&#xff0c;类似rpmbuild&#xff0c;这里创建了目录deb_build mkdir deb_build目标 我有一个hello的二进制文件hello和源码hello.c, 准备安装到/opt/helloworld目录中 步骤 在deb_build目录创建一个文件夹用于存放我的安装文件 mkdir helloworld在he…...

linux sed命令操作大全

经常使用&#xff0c;但有些总记不全&#xff0c;有时候经常查找&#xff0c;这次全部捋清楚做备忘&#xff0c;有需要的小伙伴欢迎收藏起来哦&#xff01; 查、增、改、删一应俱全&#xff0c;非常详细&#xff01; 目录 一、查看 查看第2行 查看第2行到第3行 查看第1行、…...

Vue2+Vue3组件间通信方式汇总(3)------$bus

组件间通信方式是前端必不可少的知识点&#xff0c;前端开发经常会遇到组件间通信的情况&#xff0c;而且也是前端开发面试常问的知识点之一。接下来开始组件间通信方式第三弹------$bus,并讲讲分别在Vue2、Vue3中的表现。 Vue2Vue3组件间通信方式汇总&#xff08;1&#xff09…...

前端基础location的使用

概念 获取当前页面的地址信息&#xff0c;还可以修改某些属性&#xff0c;实现页面跳转和刷新等。 样例展示 window.location 含义.originURL 基础地址&#xff0c;包括协议名、域名和端口号.protocol协议 (http: 或 https:).host域名端口号.hostname域名.port端口号.pathname路…...

Android JNI入门到基础

一、JNI项目创建 AS创建项目时选择NativeC 会创建一个基本的JNI项目 MainActivity中写java层的native方法 具体实现在cpp文件中 native-lib.cpp #include <jni.h> #include <string>extern "C" JNIEXPORT jstring JNICALL Java_com_cn_techvision_j…...

60.乐理基础-打拍子-V字打拍法

前置内容&#xff1a; 文字版 https://note.youdao.com/s/6FSSvGBf &#xff08;顺序参考&#xff1a;下方的视频版里面目录顺序&#xff09; 视频版 【四川音乐学院作曲硕士】教你零基础自学乐理保姆级教学-学习视频教程-腾讯课堂 文字版还有下图红框中三个专栏里的内容&a…...

列表对象的时间进行中文格式化处理

在黑马的项目学习中&#xff0c;如何将前端页面时间显示成2023年12月21日 06:23:23中文形式。 如果你想使用中文格式化日期&#xff0c;你可以将 en-US 更改为 zh-CN&#xff0c;以使用中文语言环境。以下是修改后的代码&#xff1a; result.data.items.forEach(item > {//…...

vi和vim的区别

目录 一、前言 二、vi/vim 的介绍 三、Vi/Vim 常见指令 四、vi和vim的区别 一、前言 写这篇文章的目的&#xff0c;是为了告诉大家我们如果要在终端下对文本进行编辑和修改可以使用vim编辑器。 Ubuntu 自带了 VI 编辑器&#xff0c;但是 VI 编辑器对于习惯了 Windows 下进…...

【昆明*线上同步】最新ChatGPT/GPT4科研实践应用与AI绘图技术及论文高效写作

详情点击查看福利&#xff1a;【昆明*线上同步】最新ChatGPT/GPT4科研实践应用与AI绘图技术及论文高效写作 目标&#xff1a; 1、熟练掌握ChatGPT提示词技巧及各种应用方法&#xff0c;并成为工作中的助手。 2、通过案例掌握ChatGPT撰写、修改论文及工作报告&#xff0c;提供…...

【解决Typora图片不是显示问题】PicGo+Github+Typora+ onedrive/坚果云 实现笔记同步

【解决Typora图片不是显示问题】PicGo、Github、Typora实现笔记同步 写在前面&#xff1a; typora笔记软件使用记录typora图片上传问题&#xff1a;原因分析&#xff1a;解决方案&#xff1a;PicGoGithubTypora 坚果云/onedrive 实现笔记同步第一步. 设置上传模式&#xff1a;u…...

使用Guava轻松创建和管理不可变集合

第1章&#xff1a;引言 大家好&#xff0c;我是小黑。今天&#xff0c;我们来聊聊一个在Java编程里超有用的话题&#xff1a;使用Guava创建和管理不可变集合。首先&#xff0c;咱们得明白&#xff0c;什么是不可变集合。简单来说&#xff0c;不可变集合就是一旦创建就不能被修…...

深入了解 Android 中的应用程序签名

深入了解 Android 中的应用程序签名 一、应用程序签名介绍1.1 应用程序签名1.2 应用程序签名的意义1.3 应用程序签名的流程1.4 应用程序签名的方案1.5 签名的重要性和应用场景 二、AOSP 的应用签名2.1 AOSP的应用签名文件路径2.2 应用程序指定签名文件 三、Android Studio 的应…...

说说 style gan 中的感知路径长度(Perceptual Path Length)

我在之前的博库中介绍了 style gan 的基本原理&#xff0c;原文中有提出感知路径长度&#xff08;Perceptual Path Length&#xff09;的概念。这是一种评价生成器质量的方式。 PPL基本思想&#xff1a;给出两个随机噪声 z 1 , z 2 ​ &#xff0c;为求得两点的感知路径长度PPL…...

基于JAVA的厦门旅游电子商务预订系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 景点类型模块2.2 景点档案模块2.3 酒店管理模块2.4 美食管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 学生表3.2.2 学生表3.2.3 学生表3.2.4 学生表 四、系统展示五、核心代码5.1 新增景点类型5.2 查询推荐的…...

uniapp中使用封装步骤条组件

针对步骤条封装完终于清清楚楚啦 先看效果&#xff1a; 附上代码&#xff1a;使用可直接复用&#xff1a;数据是写在了当前组件中&#xff0c;如有必须&#xff0c;可以使用其中的props传值stepInfos传递相应的数据&#xff0c;根据steps步数就可以控制走到哪一步啦 <temp…...

【MySQL】sum 函数和 count 函数的相同作用

力扣题 1、题目地址 1174. 即时食物配送 II 2、模拟表 配送表&#xff1a;Delivery Column NameTypedelivery_idintcustomer_idintorder_datedatecustomer_pref_delivery_datedate delivery_id 是该表中具有唯一值的列。该表保存着顾客的食物配送信息&#xff0c;顾客在某…...

在QT Creator下用CMake编译GEOS库

最近&#xff0c;想要在C下编一个可用GDAL模块的地图管理系统&#xff0c;找来找去&#xff0c;找到了GEOS。GEOS&#xff08;Geometry Engine-Open Source&#xff09;开源几何引擎 是一个用于计算几何的JTS库的 C/C实现&#xff0c;专注于地理信息系统 &#xff08;GIS&#…...

【Qt之Quick模块】4. QML语法格式及命名规范

概述 QML&#xff08;Qt Meta-Object Language&#xff09;是一种声明式语言&#xff0c;用于设计用户界面。它是由Qt框架提供的一种描述界面组件的语言&#xff0c;可以与C代码结合使用&#xff0c;用于创建跨平台的应用程序。 QML具有以下特点&#xff1a; 声明式&#xff…...

Python内置类属性__class__属性的使用教程

概要 Python作为一种高级编程语言&#xff0c;提供了丰富的功能和灵活性&#xff0c;使得开发人员能够更加方便地处理各种任务。其中一个强大的功能是内置类属性__class__属性。本文将详细介绍__class__属性的用法&#xff0c;帮助读者更好地理解和利用这一功能。 第一部分&am…...

【后台报错】插入时sql报错,varchar撑爆

后台的一个报错。按照正常的需要复现&#xff0c;或者查一下日志。但是凭借多年经验和大胆猜测&#xff0c;以及对自己代码要自信 引用一下文章 目测7*15 105项。每个id有9个数字加上分隔符刚好十个。大概就是超过了定义的一千的varchar长度。直接改数据库就好了。 简单粗暴…...

OpenSergo使用详解

简介 OpenSergo是一个基于微服务治理的标准和生态&#xff0c;覆盖了服务元信息、流量治理、服务容错、数据库/缓存治理、服务注册发现、配置治理等十几个关键领域&#xff0c;覆盖了完整的微服务生命周期&#xff08;从开发态到测试态&#xff0c;到发布态&#xff0c;再到运…...

Vanilla Pro for Mac 一款隐藏菜单栏图标工具

Vanilla Pro Vanilla Pro是一款简单易于使用的Mac应用程序&#xff0c;可让您隐藏菜单栏图标。只需下载Vanilla&#xff0c;启动应用程序&#xff0c;然后按照提示即可开始。 资源获取 Vanilla Pro for Mac 功能特性 键盘快捷键&#xff1a;设置自定义键盘快捷键来切换菜单…...

freemarkEngine文件ftl的可视化编辑

在做导出word文件功能时&#xff0c;需要准备ftl模板&#xff0c;设置一些通配符&#xff0c;之后通过相关编码&#xff0c;即可以实现业务数据渲染后导出word的功能。但是ftl文件一般我们看不太懂&#xff0c;所以可视化创建和修改就非常合适。 1、安装office2016版本&#x…...

2023 英特尔On技术创新大会直播 | 边云协同加速 AI 解决方案商业化落地

目录 前言边云协同时代背景边缘人工智能边缘挑战英特尔边云协同的创新成果最后 前言 最近观看了英特尔On技术创新大会直播&#xff0c;学到了挺多知识&#xff0c;其中对英特尔高级首席 AI 工程张宇博士讲解的边云协同加速 AI 解决方案商业化落地特别感兴趣。张宇博士讲解了英…...

电子商务网站建设也管理/近几天发生的新闻大事

asp.net编写登录注册代码 win7 asp.netms sql 2005vs2010(开发平台)数据库名userinfousername varchar(50) userpassword varchar(50) 连接数据库,写在类db.cs里面,其代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Web; usi…...

wordpress文章缩进/西安百度竞价开户

2.Spring Data Solr 入门2.1 Spring Data Solr 简介虽然支持任何编程语言的能力具有很大的市场价值&#xff0c;你可能感兴趣的问题是&#xff1a;我如何将Solr 的应用集成到 Spring 中&#xff1f;可以&#xff0c;Spring Data Solr 就是为了方便 Solr 的开发所研制的一个框架…...

上海市住房城乡建设委官方网站/什么软件能搜索关键词能快速找到

api&#xff1a; 构造函数摘要ModelAndView() bean样式用法的默认构造函数&#xff1a;填充bean属性&#xff0c;而不是传递构造函数参数。ModelAndView(Object view) 当没有模型数据暴露时&#xff0c;方便的构造函数。ModelAndView(Object view, Map mod…...

幕墙设计师培训/深圳网络优化推广公司

Log4Dom是模仿Log4J的思想建立的。Log4J能够向多种记录媒介以统一的格式写入各种级别的日志信息&#xff08;包括错误、调试和信息等&#xff09;&#xff0c;还可以籍配置文件在运行时方便地修改记入日志的级别。Log4Dom提供了类似的功能。现在我们就来看看它的各部分元素和代…...

安庆城乡建设局网站/国产免费crm系统有哪些在线

说明 POI可以对2003-和2007版本的Excel文件做导入导出操作&#xff0c;本章只简单介绍对Excel文件的导入操作。 Excel文件的上传处理处理请求&#xff0c;依然使用SpringMvc中的MultipartRequest方式处理。前端JSP中使用传统form表单提交方式。环境 MavenJDK6 Tomcat7.x Sprin…...

wordpress后台操作教程/昭通网站seo

今天看视频教程无意间看到了一个数3减1的问题&#xff0c;百度之发现叫约瑟夫环问题&#xff0c;于是写了程序&#xff0c;问题大致描述如下&#xff1a; 一群带有编号的孩子手拉手围成一个圈报数&#xff0c;开始的孩子数1&#xff0c;他右边数2&#xff0c;再右边数3&#xf…...