一、Feign与OpenFeign的区别

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

Feign的依赖

1 <dependency>
2     <groupId>org.springframework.cloud</groupId>
3     <artifactId>spring-cloud-starter-feign</artifactId>
4 </dependency>
  • 2)OpenFeign是Spring Cloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中.

OpenFeign的依赖

1 <dependency>
2     <groupId>org.springframework.cloud</groupId>
3     <artifactId>spring-cloud-starter-openfeign</artifactId>
4 </dependency>  

说明:
springcloud F 及F版本以上 springboot 2.0 以上基本上使用openfeign,openfeign 如果从框架结构上看就是2019年feign停更后出现版本,也可以说大多数新项目都用openfeign ,2018年以前的项目在使用feign

二、openFeign教程

Spring-Cloud-OpenFeign使用教程 - 知乎

Spring Cloud OpenFeign使用教程

Spring Cloud OpenFeign Demo

之前项目中需要在Spring Cloud中使用OpenFeign的情况,Spring Cloud的版本是目前最新的Greenwich.SR2版本,对应的Spring boot是2.1.7.RELEASE。

在网上找了很多资料,大多言之不详,并且版本也比较低,不适合我的最新版本Spring Cloud的需求。 所以决定还是自己写个教程。

本教程要解决如下几个问题:

  1. 怎么配置OpenFeignServer
  2. 怎么配置OpenFeignClient
  3. 多个参数传递问题
  4. FeignClient的日志问题
  5. 多个FeignClient使用同一个name的问题

怎么配置OpenFeignServer

我们知道OpenFeign是用在Spring Cloud中的声明式的web service client。

OpenFeignServer就是一个普通的Rest服务,不同的是我们需要将他注册到eureka server上面,方便后面的OpenFeignClient调用。

启动类如下:

@SpringBootApplication
@EnableDiscoveryClient
public class OpenFeignServer {public static void main(String[] args) {SpringApplication.run(OpenFeignServer.class, args);}
}

我们定义了两个Rest服务:

OrderController:

@Slf4j
@RestController
@RequestMapping(path = "/order")
public class OrderController {/*** PostMapping with @RequestBody* @param user*/@PostMapping("doOrder")public void doOrder(@RequestBody User user){log.info("do order !!!!");}
}

UserController:

@RestController
@RequestMapping(path = "/user")
public class UserController {/*** GetMapping example with @RequestParam* @param userId* @return userName*/@GetMapping("getUserName")public String getUserName(@RequestParam("userId") String userId){if("100".equals(userId)) {return "张学友";}else{return "刘德华";}}/*** GetMapping example with @RequestParam and @SpringQueryMap* @param userId* @param user* @return userAge*/@GetMapping("getUserAge")public String getUserAge(@RequestParam("userId") String userId, @SpringQueryMap User user){if("100".equals(userId)) {return "20";}else{return "18";}}
}

我们将其注册到eureka上面,名字为openfeign-server

spring:application:name: openfeign-server

怎么配置OpenFeignClient

OpenFeignClient的pom依赖如下:

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

启动类上增加@EnableFeignClients注解,告诉框架扫描所有使用注解@FeignClient定义的feign客户端,并把feign客户端注册到IOC容器中。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({FeignClientsRegistrar.class})
public @interface EnableFeignClients {String[] value() default {};String[] basePackages() default {};Class<?>[] basePackageClasses() default {};Class<?>[] defaultConfiguration() default {};Class<?>[] clients() default {};
}

需要使用@FeignClient来注解一个interface,如下所示:

@FeignClient(value = "openfeign-server")
@RequestMapping(path = "/user")
public interface UserClient {@GetMapping("getUserName")public String getUserName(@RequestParam("userId") String userId);@GetMapping("getUserAge")public String getUserAge(@RequestParam("userId") String userId, @SpringQueryMap User user);
}

其中@FeignClient中的value是要调用的服务的注册名,即OpenFeignServer在eureka的注册名。

FeignClient的 Request路径,方式和参数要和被调用的Rest服务保持一致。

这样我们就可以像下面一样来调用OpenFeignClient了:

@Slf4j
@RestController
public class UserController {@Autowiredprivate UserClient userClient;@GetMapping("getUserName2")public void getUserName(){log.info(userClient.getUserName("100"));}
}

查看FeignClient注解代码如下:

public @interface FeignClient {@AliasFor("name")String value() default "";String contextId() default "";@AliasFor("value")String name() default "";String qualifier() default "";String url() default "";boolean decode404() default false;Class<?>[] configuration() default {};Class<?> fallback() default void.class;Class<?> fallbackFactory() default void.class;String path() default "";boolean primary() default true;
}

下面就对各个属性进行分析:

value、name
value和name的作用一样,如果没有配置url那么配置的值将作为服务名称,用于服务发现。反之只是一个名称。value和name必须配一个

contextId
我们不想将所有的调用接口都定义在一个类中,有一种解决方案就是为每个Client手动指定不同的contextId,这样就不会冲突了。

url
url用于配置指定服务的地址,相当于直接请求这个服务,不经过Ribbon的服务选择。像调试等场景可以使用。

decode404
当调用请求发生404错误时,decode404的值为true,那么会执行decoder解码,否则抛出异常。

configuration
configuration是配置Feign配置类,在配置类中可以自定义Feign的Encoder、Decoder、LogLevel、Contract等。

fallback
定义容错的处理类,也就是回退逻辑,fallback的类必须实现Feign Client的接口,无法知道熔断的异常信息。(不推荐)

fallbackFactory
也是容错的处理,可以知道熔断的异常信息。(推荐)
注意!客户端要熔断降级必须在yaml文件里进行配置,客户端:

feign:hystrix:enabled:true

path
path定义当前FeignClient访问接口时的统一前缀,比如接口地址是/user/get, 如果你定义了前缀是user, 那么具体方法上的路径就只需要写/get 即可。

primary
primary对应的是@Primary注解,默认为true,官方这样设置也是有原因的。当我们的Feign实现了fallback后,也就意味着Feign Client有多个相同的Bean在Spring容器中,当我们在使用@Autowired进行注入的时候,不知道注入哪个,所以我们需要设置一个优先级高的,@Primary注解就是干这件事情的。

qualifier
qualifier对应的是@Qualifier注解,使用场景跟上面的primary关系很淡,一般场景直接@Autowired直接注入就可以了。

第三方调用,在项目使用openFeign:(入参可以是json对象/实体/json字符串,返回值类型对应起来即可)

package com.oceansite.system.api;import com.alibaba.fastjson.JSONObject;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;/*** @ClassName: RemoteNavigationService* @Description: * @Author: * @Date: 2022/3/29 9:36**/
@FeignClient(contextId = "remoteNavigationService",url = "https://xcx.apsatcom.com/OSN/api/prod",name = "navigation")
//上面远程调用的url是写死的,可以通过增加uri入参,实现动态url,见文末
public interface RemoteNavigationService {/***@Description: 小站列表接口*@Author: yangfengfan*@Param: [jsonObject]*@Return: com.oceansite.system.api.domain.Result*@Date: 2022/3/29 10:53**/@PostMapping(value = "/terminal/group/v1",headers = {"accept-encoding=gzip","content-type=application/json; charset=UTF-8","accept=application/json"})public JSONObject getTerminalGroupPage2(@RequestBody JSONObject navigationData);/***@Description: 小站实时信息查询接口*@Author: yangfengfan*@Param: [jsonObject]*@Return: com.oceansite.system.api.domain.Result*@Date: 2022/3/29 10:53**/@PostMapping(value = "/terminal/status/v1",headers = {"accept-encoding=gzip","content-type=application/json; charset=UTF-8","accept=application/json"})public JSONObject getListTerminalByParm(@RequestBody JSONObject navigationData);/***@Description: 小站数据发送接收链路接口*@Author: yangfengfan*@Param: [jsonObject]*@Return: com.oceansite.system.api.domain.Result*@Date: 2022/3/29 10:53**/@PostMapping(value = "/nms/ucp/v1",headers = {"accept-encoding=gzip","content-type=application/json; charset=UTF-8","accept=application/json"})public JSONObject qeryNmsUcpInfo(@RequestBody JSONObject navigationData);
}

多个参数传递问题

一般我们会使用@GetMapping和@PostMapping两种方式来调用Rest服务。

而接收的参数则会使用@RequestParam和@RequestBody来获取。

首先我们讲一下@RequestBody,@RequestBody只能用在Post请求,并且一个Post请求只能有一个@RequestBody。 @RequestBody的参数可以包括复杂类型。

然后我们讲一下@RequestParam,@RequestParam可以用在Post和Get请求中,但是要注意:@RequestParam 的参数只能是基本类型或者Enum,或者List和Map(List和Map里面也只能是基本类型)。所以@RequestParam可以和@RequestBody一起使用。

如果我们是Get请求,但是又有复合类型怎么办? 比如我们想传递一个User对象。User对象里面只有普通的两个String属性。 这里我们可以使用@SpringQueryMap:

    @GetMapping("getUserAge")public String getUserAge(@RequestParam("userId") String userId, @SpringQueryMap User user);

注意:@SpringQueryMap后面的参数只能是普通的POJO,不能是复合类型,否则解析不了。如果必须使用复合类型,那么使用@RequestBody吧。

FeignClient的日志问题

OpenFeign的Logger.Level有4种级别:

  • NONE 没有日志
  • BASIC 请求方法,请求URL,返回Code和执行时间
  • HEADERS 请求和返回的头部基本信息
  • FULL 请求和返回的头部,内容,元数据

要想使用这些级别,必须将OpenFeignClient的logger设置成debug级别:

#日志配置
logging:level:com:flydean: debug

同时我们在代码中配置OpenFeign的日志级别:

@Configuration
public class CustFeignLogConfig {@BeanLogger.Level feignLoggerLevel() {return Logger.Level.FULL;}
}

这样我们在日志里面就可以看到DEBUG的所有HTTP请求信息。

多个FeignClient使用同一个name的问题

其实这里我们的Server定义了两个Rest服务,User和Order。

上面我们讲到了可以这样定义UserClient:

@FeignClient(value = "openfeign-server")
@RequestMapping(path = "/user")
public interface UserClient {...
}

如果我们同样的这样定义OrderClient:

@FeignClient(value = "openfeign-server")
@RequestMapping(path = "/order")
public interface OrderClient {...
}

运行时候就会报错。 原因是两个FeignClient使用了同一个value!

那怎么解决这个问题呢?

/*** 因为@FeignClient的value不能重复,所以需要在这里以自定义的方式来创建* @author wayne* @version FeignClientController,  2019/9/5 7:07 下午*/
@Data
@Component
@Import(FeignClientsConfiguration.class)
public class FeignClientController {private OrderClient orderClient;private UserClient userClient;public FeignClientController(Decoder decoder, Encoder encoder, Client client, Contract contract) {this.orderClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)//默认是Logger.NoOpLogger.logger(new Slf4jLogger(OrderClient.class))//默认是Logger.Level.NONE.logLevel(Logger.Level.FULL).target(OrderClient.class, "http://openfeign-server");this.userClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)//默认是Logger.NoOpLogger.logger(new Slf4jLogger(UserClient.class))//默认是Logger.Level.NONE.logLevel(Logger.Level.FULL).target(UserClient.class, "http://openfeign-server");}
}

方法就是手动创建FeignClient, 上面的例子中,我们手动创建了OrderClient和UserClient两个FeignClient。

注意下面的代码片段,手动创建的FeignClient默认是没有logger和logLevel的。所以上面我们配置好的log信息对手动创建的FeignClient是无效的。 下面展示了如何手动添加:

//默认是Logger.NoOpLogger.logger(new Slf4jLogger(OrderClient.class))//默认是Logger.Level.NONE.logLevel(Logger.Level.FULL)

超时控制介绍

默认Feign客户端只等待一秒钟,但是服务霭处理需要超过1秒,导致Feign客户端不想等待了,直接返回报错。为了避免这样的情况,有时候我们需要设置Feign客户端的超时控制。
解决方法:ym|文件中开启配置,application.yml

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

没配置上面的yml文件时,如果我们调用如下的方法会报错

 @GetMapping("/feign/timeout")public String paymentFeignTimeout() {try {TimeUnit.SECONDS.sleep(4);} catch (InterruptedException e) {e.printStackTrace();}return serverPort;}

配置了,就会出现以下结果

如何运行

本项目的模块都是以spring boot构建的,直接在编译器中运行Main方法即可启动。

  1. 启动openfeign-registry-server

openfeign-registry-server会启动eureka server,供后面的OpenFeignServer和OpenFeignClient注册。

  1. 启动openfeign-server
  2. 启动openfeign-client

  3. 测试openFeignClient

get请求url: http://localhost:8000/getUserName1

查看日志,看看输出吧。

本项目代码地址 :spring-cloud-openfeign-demo

更多教程请参考 flydean的博客

三、OpenFeign配置文件详解

Feign 配置文件详解_丶自定义-CSDN博客_feign 配置文件

可以在应用程序中指定 application.properties / application.properties 文件,或作为命令行开关。本附录提供了通用Spring Cloud OpenFeign属性的列表,以及对使用它们的底层类的引用。

配置项 默认值 描述

feign.client.config

feign.client.default-config

default

feign.client.default-to-properties

true

feign.compression.request.enabled

false

配置请求GZIP压缩。

feign.compression.request.mime-types

[text/xml, application/xml, application/json]

配置压缩支持的MIME TYPE

feign.compression.request.min-request-size

2048

配置压缩数据大小的下限

feign.compression.response.enabled

false

配置响应GZIP压缩。

feign.compression.response.useGzipDecoder

false

启用默认的gzip解码器。

feign.httpclient.connection-timeout

2000

连接超时时间(单位:秒)

feign.httpclient.connection-timer-repeat

3000

feign.httpclient.disable-ssl-validation

false

feign.httpclient.enabled

true

开启(true)/关闭(false) Apache HTTP请求方式

feign.httpclient.follow-redirects

true

feign.httpclient.max-connections

200

线程池最大连接数(全局)

feign.httpclient.max-connections-per-route

50

线程池最大连接数(单个HOST)

feign.httpclient.time-to-live

900

线程存活时间(单位:秒)

feign.httpclient.time-to-live-unit

feign.hystrix.enabled

false

开启(true)/关闭(false)Hystrix功能

feign.okhttp.enabled

false

开启(true)/关闭(false) OK HTTP请求方式

Feign提供了两大类配置属性来配置上述三种HTTP客户端,feign.client.*和feign.httpclient.*,前者支持按实例进行配置(注解-1),后者全局共享一套配置,包含线程池配置,但只影响HttpClient和OkHttp,不影响HttpURLConnection,具体关系见下表。

注解-1:所谓按实例进行配置,就是指每个FeignClient实例都可以通过feign.client.<feignClientName>.*来单独进行配置,注意首字母小写。而feign.client.default.*表示默认配置。

HTTP客户端 连接超时时间 请求超时时间 线程存活时间 线程池最大连接数(全局) 线程池最大连接数(单个HOST)
HttpURLConnection feign.client.[default|<feignClientName>].connect-timeout
默认值:10秒
feign.client.[default|<feignClientName>].read-timeout
默认值:60秒
N/A N/A N/A
HttpClient feign.httpclient.connection-timeout
默认值:2秒

默认值:

-1(RequestConfig.Builder.socketTimeout)

feign.httpclient.time-to-live
默认值:900秒
feign.httpclient.max-connections
默认值:200
feign.httpclient.max-connections-per-route
默认值:50
OkHttp feign.httpclient.connection-timeout
默认值:2秒
feign.client.[default|<feignClientName>].read-timeout
默认值:10秒
feign.httpclient.time-to-live
默认值:900秒
feign.httpclient.max-connections
默认值:200
N/A

从上表可以看到,Feign提供了两个连接超时配置,HttpURLConnection使用feign.client.[default|<feignClientName>].connect-timeout,而HttpClient和OkHttp则使用feign.httpclient.connection-timeout,这一点要尤其注意。

参考地址:

【Spring Cloud】详解Feign常用配置

 Spring Cloud OpenFeign

遇到的问题1:动态URL问题:

//url必须写一个默认的,是什么不重要,执行时会被替换@FeignClient(contextId = "remoteDataFlowService",url = "http://58.254.146.130:8989/OSN/api/test1",name = "DataFlow")
public interface RemoteDataFlowService {/***@Description: 余额查询接口*@Author: yangfengfan*@Param: [jsonObject]*@Return: com.oceansite.system.api.domain.Result*@Date: 2022/3/29 10:53**/@PostMapping(value = "/payment/detail/v1",headers = {"accept-encoding=gzip","content-type=application/json; charset=UTF-8","accept=application/json"})JSONObject getBalanceInquiry(@RequestParam(value = "uri")URI uri, @RequestBody String DataFlowData);-------------------------------------------------------------------------------@Value("${asiapacific6d.dataflow.url}")String url;@PostMapping("/payment/detail/v1")public JSONObject getBalanceInquiry(@RequestBody DataFlowData dataFlowData) throws URISyntaxException {JSONObject json = (JSONObject) JSONObject.toJSON(dataFlowData);System.out.println(json.toJSONString());return remoteDataFlowService.getBalanceInquiry(new URI(url),json.toJSONString());}

在入参中加入URI参数,就可以支持url可配置,调试多个环境的时候有用。

openfeign 实现动态Url - lshan - 博客园

OpenFeign中动态URl_wangdaoyin2010的博客-CSDN博客_openfeign 动态url

遇到的问题2:nested exception is java.lang.IllegalStateException: RequestParam.value() was empty on parameter 0

@FeignClient注解下的类似@RequestParam注解等一定要有value属性

遇到的问题3:

结论:@FeignClient  configuration 指定的配置类不要加 @Configuration,如果加了@Configuration注解,那这个配置类就是一个全局配置类。

@FeignClient configuration参数配置_Riven Chen的博客-CSDN博客(重要)

@FeignClient中的configuration使用拦截器,可以给微服务间的调用,增加参数或鉴权使用

@FeignClient(name = "weixinService", url = "https://api.weixin.qq.com",configuration = WeiXinInterceptor.class)
public interface WeiXinService {

下方的拦截器如果类上加@Configuration,那么全局生效,如果不加,则@FeignClient指定生效。

package com.byd.msp.gateway.fegin.wexin;import feign.Client;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;/*** 微信接口统一鉴权*/
@Component
public class WeiXinInterceptor implements RequestInterceptor {/*** 小程序 appId*/@Value("${wechat.app_id:xxxxx}")private String appId;/*** 小程序 appSecret*/@Value("${wechat.app_secret:xxxxxx}")private String secret;@Overridepublic void apply(RequestTemplate requestTemplate) {requestTemplate.query("appid", appId);requestTemplate.query("secret", secret);requestTemplate.query("grant_type", "authorization_code");}@Beanpublic Client generateClient() {try {SSLContext ctx = SSLContext.getInstance("SSL");X509TrustManager tm = new X509TrustManager() {@Overridepublic void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}@Overridepublic void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}};ctx.init(null, new TrustManager[]{tm}, new SecureRandom());return new Client.Default(ctx.getSocketFactory(), (hostname, session) -> true);} catch (NoSuchAlgorithmException e) {throw new RuntimeException(e);} catch (KeyManagementException e) {throw new RuntimeException(e);}}
}

遇到的问题4:feign远程调用公共api模块,一直报错null。(重要)

第一个是依赖问题,没有注入CodeDictionaryProviderFallback的依赖直接启动报错,通过该方式解决:SpringBoot启动类默认自动扫描包范围 + spring.factories理解_spring boot 包扫描范围_keep one's resolveY的博客-CSDN博客

第二个是公共api模块@FeignClient的接口没有被加载,使用@EnableFeignClients注解的属性字段basePackages解决

一般情况下,我们在启动类上面添加了@EnableFeignClients注解就是表明当前应用服务(我们称之为服务A)中有的地方想要引用其它应用服务(我们称之为服务B)中的接口。

如果服务B可以单独启动起来并且注册到注册中心,则我们仅仅在服务A的启动类中添加@EnableFeignClients注解即可;如果服务B没有单独启动起来,而是以Jar包的形式被引入到服务A中,则服务A在启动的时候是不会主动去加载服务B中标注了@FeignClient注解的interface而去自动生成bean对象。这个时候就需要使用basePackages属性字段去指明应用程序A在启动的时候需要扫描服务B中的标注了@FeignClient注解的接口的包路径。

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {"com.bc.product.client"})
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}
}

遇到的问题5:3.8版本以下,openfeign远程调用上传多个文件时报错

通过Feign 的方式 进行调用,feign 调用的本质还是http内部通信请求,实现模块之间的调用。

通过feign进行文件上传时,feign 侧示例代码如下:

@FeignClient
public interface UploadClient {@PostMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)String uploadFile(@RequestPart(value = "file") MultipartFile file, @RequestParam String uploadPath);
}

文件属性需要使用 @RequestPart 属性,而且在请求中添加 consumes = MediaType.MULTIPART_FORM_DATA_VALUE ,

文件表单上传请求通常使用的ContentType为 multipart/form-data ,通过以上直接调用feign的方式即可实现feign 文件上传。

@RequestPart 与 @RequestParam 的区别:

1. @RequestPart这个注解用在multipart/form-data表单提交请求的方法上。
2. 支持的请求方法的方式MultipartFile,属于Spring的MultipartResolver类。这个请求是通过http协议传输的。
3. @RequestParam也同样支持multipart/form-data请求。
4. 他们最大的不同是,当请求方法的请求参数类型不再是String类型的时候。
5. @RequestParam适用于name-valueString类型的请求域,@RequestPart适用于复杂的请求域(像JSON,XML)。

Feign实现多文件上传,Open Feign多文件上传问题及解决_java_脚本之家(feignFormEncoder的bean上需要加@Primary)

@Scope注解 详细讲解及示例_扛麻袋的少年的博客-CSDN博客

Feign接口实现上传多个文件的坑_feign多文件上传_油腻的程序猿啊的博客-CSDN博客

feign和openFeign区别和openFeign教程相关推荐

  1. SpringClound——Feign和OpenFeign区别和OpenFeign的使用

    Feign和OpenFeign的主要区别如下图 那我们怎么使用OpenFeign呢? 文章目录 1:OpenFeign服务调用 2:OpenFeign超时控制 3:OpenFeign日志增强 1:Op ...

  2. openfeign ribbon 负载_SpringCloud教程(三)声明式访问Feign、负载均衡Ribbon

    0-前言 eureka实际上已经集成了负载均衡调度框架Ribbon: 我们有了各个微服务了,那怎么来调用他们呢,一种方法是可以使用 RestTemplate(如:String str= restTem ...

  3. Spring Cloud 系列之OpenFeign:(5)OpenFeign的高级用法

    传送门 Spring Cloud Alibaba系列之nacos:(1)安装 Spring Cloud Alibaba系列之nacos:(2)单机模式支持mysql Spring Cloud Alib ...

  4. php在类定义一个我静态变量,php中静态类与静态变量用法的区别分析_PHP教程

    php中静态类与静态变量用法的区别分析 static是定义一个静态对象或静态变量,关于static 定义的变量或类方法有什么特性我们看完本文章的相关实例后就见分晓了. 1. 创建对象$object = ...

  5. Java后端开发 — Forest、Feign、Retrofit区别

    1. Forest和Feign的区别? Feign和Forest都是基于注解的声明式HTTP框架,但封装程度和api接口风格不太相同 比如:Feign没有封装SSL证书验证.连接池.正向代理等功能,需 ...

  6. python 类方法 实例方法的区别_python基础教程Python实例方法、类方法、静态方法区别详解...

    1.关于参数的区别 实例方法:定义实例方法是最少有一个形参 ---> 实例对象,通常用 self 类方法:定义类方法的时候最少有一个形参 ---> 类对象,通常用 cls 静态方法:定义静 ...

  7. mysql join union_MySQL中union和join语句使用区别的辨析教程

    union和join是需要联合多张表时常见的关联词,具体概念我就不说了,想知道上网查就行,因为我也记不准确. 先说差别:union对两张表的操作是合并数据条数,等于是纵向的,要求是两张表字段必须是相同 ...

  8. python中out什么意思_ref和out的使用与区别|python基础教程|python入门|python教程

    https://www.xin3721.com/eschool/pythonxin3721/ out的使用 ---------------------------------------------- ...

  9. java里的nextint_「nextint」Java中关于nextInt()、next()和nextLine()的区别 - 金橙教程网...

    nextint 先看解释: nextInt(): it only reads the int value, nextInt() places the cursor in the same line a ...

最新文章

  1. Roundgod and Milk Tea 贪心
  2. Hadoop掀起大数据革命 三巨头齐发力
  3. 定义简单类-创建多个猫对象
  4. Windows10家庭中文版没有本地策略选项完美解决方案
  5. C语言试题十六之写删除字符串中指定下标的字符。其中,a指向原字符串,删除后的字符串存放在b所指的数组中,n中存放指定的下标。
  6. 安装和使用Ant Design Vue 图标库
  7. 调参方法论:如何提高机器学习模型的性能?
  8. paper 108:系统学习数字图像处理之图像复原与重建
  9. Pulseaudio之nemo(二十二)
  10. 基于MVC的JavaScriptWeb富应用开发
  11. wps python 自动化_用Python控制Excel实现自动化办公,手把手教你
  12. python界面实现点餐系统_餐厅点餐系统详细设计与系统实现
  13. Windows配置maven环境变量
  14. 《我的青春谁做主》经典搞笑台词
  15. 用Prolog解决数独
  16. 【数字信号处理】FIR 滤波器基础理论
  17. 飞车手游显示服务器连接失败怎么办,qq飞车手游服务器拉取失败
  18. AM335X-IO输入总是读不到输入电平——8
  19. 把数字翻译成中文的计算机,数字翻译成中文,把数字翻译成中文
  20. PySide2学习总结(十二)打开文件对话框--FileDialog

热门文章

  1. 餐饮管理能力测试软件,餐饮管理系统设计和测试.doc
  2. 【深度学习】深度解读:深度学习在IoT大数据和流分析中的应用
  3. 微信红包封面制作小程序开放,人人都可免费制作了!!!
  4. 一个数据采集系统的设计及重要点
  5. apicloud地图导航
  6. SQL查询一个表中类别字段中Max()最大值对应的记录
  7. 【Java常用工具类汇总 2,零基础如何成为高级Java开发
  8. 运城学院计算机系有什么专业,运城学院有哪些专业及什么专业好
  9. 买的天猫转让网店怎么变更品牌
  10. 计算机组成原理——存储系统の选择题整理